@typeberry/lib 0.8.4-faebc7a → 0.9.0-3f2c45b
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/package.json +1 -1
- package/packages/configs/index.d.ts +30 -1
- package/packages/configs/index.d.ts.map +1 -1
- package/packages/configs/index.js +4 -2
- package/packages/configs/typeberry-dev-full.json +29 -0
- package/packages/core/bytes/bytes.d.ts +1 -0
- package/packages/core/bytes/bytes.d.ts.map +1 -1
- package/packages/core/bytes/bytes.js +8 -0
- package/packages/core/utils/debug.d.ts +4 -2
- package/packages/core/utils/debug.d.ts.map +1 -1
- package/packages/core/utils/debug.js +18 -13
- package/packages/core/utils/debug.test.js +12 -6
- package/packages/jam/config-node/node-config.d.ts +2 -1
- package/packages/jam/config-node/node-config.d.ts.map +1 -1
- package/packages/jam/config-node/node-config.js +8 -3
- package/packages/jam/config-node/node-config.test.js +3 -3
- package/packages/jam/database-fjall/hybrid-states.d.ts +47 -10
- package/packages/jam/database-fjall/hybrid-states.d.ts.map +1 -1
- package/packages/jam/database-fjall/hybrid-states.js +78 -22
- package/packages/jam/database-fjall/hybrid-states.test.js +31 -1
- package/packages/jam/database-fjall/root.d.ts +18 -12
- package/packages/jam/database-fjall/root.d.ts.map +1 -1
- package/packages/jam/database-fjall/root.js +14 -10
- package/packages/jam/jamnp-s/tasks/ticket-distribution.js +1 -1
- package/packages/jam/node/main-fuzz.d.ts.map +1 -1
- package/packages/jam/node/main-fuzz.js +53 -10
- package/packages/jam/node/main-importer.d.ts +8 -1
- package/packages/jam/node/main-importer.d.ts.map +1 -1
- package/packages/jam/node/main-importer.js +2 -1
- package/packages/jam/safrole/bandersnatch-vrf.d.ts +22 -2
- package/packages/jam/safrole/bandersnatch-vrf.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-vrf.js +54 -20
- package/packages/jam/safrole/bandersnatch-vrf.test.js +3 -2
- package/packages/jam/safrole/bandersnatch-wasm.d.ts +10 -0
- package/packages/jam/safrole/bandersnatch-wasm.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-wasm.js +12 -0
- package/packages/jam/ticket-pool/ticket-validator.d.ts +5 -4
- package/packages/jam/ticket-pool/ticket-validator.d.ts.map +1 -1
- package/packages/jam/ticket-pool/ticket-validator.js +8 -3
- package/packages/jam/ticket-pool/ticket-validator.test.js +5 -4
- package/packages/jam/ticket-pool/verified-ticket-pool.d.ts +2 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.d.ts.map +1 -1
- package/packages/jam/ticket-pool/verified-ticket-pool.js +4 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.test.js +5 -5
- package/packages/workers/api-node/config.d.ts +14 -6
- package/packages/workers/api-node/config.d.ts.map +1 -1
- package/packages/workers/api-node/config.js +15 -11
- package/packages/workers/block-authorship/{generator.d.ts → block-generator.d.ts} +5 -5
- package/packages/workers/block-authorship/block-generator.d.ts.map +1 -0
- package/packages/workers/block-authorship/{generator.js → block-generator.js} +3 -3
- package/packages/workers/block-authorship/block-generator.test.d.ts +2 -0
- package/packages/workers/block-authorship/block-generator.test.d.ts.map +1 -0
- package/packages/workers/block-authorship/{generator.test.js → block-generator.test.js} +8 -8
- package/packages/workers/block-authorship/epoch-authoring-slots.d.ts +35 -0
- package/packages/workers/block-authorship/epoch-authoring-slots.d.ts.map +1 -0
- package/packages/workers/block-authorship/epoch-authoring-slots.js +86 -0
- package/packages/workers/block-authorship/epoch-tracker.d.ts +29 -0
- package/packages/workers/block-authorship/epoch-tracker.d.ts.map +1 -0
- package/packages/workers/block-authorship/epoch-tracker.js +80 -0
- package/packages/workers/block-authorship/index.d.ts.map +1 -1
- package/packages/workers/block-authorship/index.js +1 -1
- package/packages/workers/block-authorship/main.d.ts +3 -0
- package/packages/workers/block-authorship/main.d.ts.map +1 -1
- package/packages/workers/block-authorship/main.js +193 -261
- package/packages/workers/block-authorship/ticket-generator/bootstrap-main.d.ts +2 -0
- package/packages/workers/block-authorship/ticket-generator/bootstrap-main.d.ts.map +1 -0
- package/packages/workers/block-authorship/ticket-generator/bootstrap-main.js +23 -0
- package/packages/workers/block-authorship/ticket-generator/index.d.ts +16 -0
- package/packages/workers/block-authorship/ticket-generator/index.d.ts.map +1 -0
- package/packages/workers/block-authorship/ticket-generator/index.js +62 -0
- package/packages/workers/block-authorship/ticket-generator/protocol.d.ts +50 -0
- package/packages/workers/block-authorship/ticket-generator/protocol.d.ts.map +1 -0
- package/packages/workers/block-authorship/ticket-generator/protocol.js +54 -0
- package/packages/workers/block-authorship/{ticket-generator.d.ts → ticket-generator/ticket-generator.d.ts} +4 -0
- package/packages/workers/block-authorship/ticket-generator/ticket-generator.d.ts.map +1 -0
- package/packages/workers/block-authorship/{ticket-generator.js → ticket-generator/ticket-generator.js} +19 -9
- package/packages/workers/block-authorship/ticket-generator/ticket-generator.test.d.ts.map +1 -0
- package/packages/workers/block-authorship/{ticket-generator.test.js → ticket-generator/ticket-generator.test.js} +13 -9
- package/packages/workers/block-authorship/ticket-generator/worker-pool.d.ts +36 -0
- package/packages/workers/block-authorship/ticket-generator/worker-pool.d.ts.map +1 -0
- package/packages/workers/block-authorship/ticket-generator/worker-pool.js +111 -0
- package/packages/workers/block-authorship/ticket-validator.d.ts +7 -8
- package/packages/workers/block-authorship/ticket-validator.d.ts.map +1 -1
- package/packages/workers/block-authorship/ticket-validator.js +26 -23
- package/packages/workers/comms-authorship-network/protocol.d.ts +4 -4
- package/packages/workers/comms-authorship-network/protocol.d.ts.map +1 -1
- package/packages/workers/comms-authorship-network/protocol.js +4 -5
- package/packages/workers/comms-authorship-network/tickets-message.d.ts +0 -14
- package/packages/workers/comms-authorship-network/tickets-message.d.ts.map +1 -1
- package/packages/workers/comms-authorship-network/tickets-message.js +0 -17
- package/packages/workers/importer/importer.d.ts +2 -2
- package/packages/workers/importer/importer.d.ts.map +1 -1
- package/packages/workers/importer/importer.js +5 -5
- package/packages/workers/importer/stats.d.ts +1 -3
- package/packages/workers/importer/stats.d.ts.map +1 -1
- package/packages/workers/importer/stats.js +12 -12
- package/packages/workers/jam-network/main.d.ts.map +1 -1
- package/packages/workers/jam-network/main.js +8 -3
- package/packages/workers/block-authorship/generator.d.ts.map +0 -1
- package/packages/workers/block-authorship/generator.test.d.ts +0 -2
- package/packages/workers/block-authorship/generator.test.d.ts.map +0 -1
- package/packages/workers/block-authorship/ticket-generator.d.ts.map +0 -1
- package/packages/workers/block-authorship/ticket-generator.test.d.ts.map +0 -1
- /package/packages/configs/{typeberry-dev.json → typeberry-dev-tiny.json} +0 -0
- /package/packages/workers/block-authorship/{ticket-generator.test.d.ts → ticket-generator/ticket-generator.test.d.ts} +0 -0
|
@@ -71,6 +71,7 @@ export declare class Bytes<T extends number> extends BytesBlob {
|
|
|
71
71
|
isEqualTo(other: Bytes<T>): boolean;
|
|
72
72
|
/** Converts current type into some opaque extension. */
|
|
73
73
|
asOpaque<R>(): Opaque<Bytes<T>, TokenOf<R, Bytes<T>>>;
|
|
74
|
+
toStringTruncated(): string;
|
|
74
75
|
}
|
|
75
76
|
export declare const bytesBlobComparator: Comparator<BytesBlob>;
|
|
76
77
|
//# sourceMappingURL=bytes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../../../../packages/core/bytes/bytes.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../../../../packages/core/bytes/bytes.ts"],"names":[],"mappings":"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"}
|
|
@@ -197,6 +197,14 @@ export class Bytes extends BytesBlob {
|
|
|
197
197
|
asOpaque() {
|
|
198
198
|
return asOpaqueType(this);
|
|
199
199
|
}
|
|
200
|
+
toStringTruncated() {
|
|
201
|
+
if (this.raw.length > 8) {
|
|
202
|
+
const start = bytesToHexString(this.raw.subarray(0, 2));
|
|
203
|
+
const end = bytesToHexString(this.raw.subarray(this.raw.length - 2));
|
|
204
|
+
return `${start}...${end.substring(2)}`;
|
|
205
|
+
}
|
|
206
|
+
return `${this.toString()}`;
|
|
207
|
+
}
|
|
200
208
|
}
|
|
201
209
|
function byteFromString(s) {
|
|
202
210
|
check `${s.length === 2} Two-character string expected`;
|
|
@@ -59,9 +59,11 @@ export declare function measure(id: string): () => {
|
|
|
59
59
|
* `arrayBuffers` should allow tracking WASM memory, since every instance backs its
|
|
60
60
|
* memory with `ArrayBuffer`.
|
|
61
61
|
*/
|
|
62
|
-
export declare function memoryUsage(): string;
|
|
62
|
+
export declare function memoryUsage(withDetails: boolean): string;
|
|
63
63
|
/** Create a stateful memory usage reporter. */
|
|
64
|
-
export declare function memoryTracker(
|
|
64
|
+
export declare function memoryTracker(withDetails: boolean): {
|
|
65
|
+
toString(): string;
|
|
66
|
+
};
|
|
65
67
|
/** A class that adds `toString` method that prints all properties of an object. */
|
|
66
68
|
export declare abstract class WithDebug {
|
|
67
69
|
toString(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../../../packages/core/utils/debug.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,YAExB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,cAA6F,CAAC;AAE9G;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,OAAO,EAClB,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,SAAS,IAAI,IAAI,CAO3B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,QAKpE;AAED,6BAA6B;AAC7B,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAEzC;AAkED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;EAgBjC;AAcD;;;;;;;GAOG;AACH,wBAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../../../packages/core/utils/debug.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,YAExB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,cAA6F,CAAC;AAE9G;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,OAAO,EAClB,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,SAAS,IAAI,IAAI,CAO3B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,QAKpE;AAED,6BAA6B;AAC7B,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAEzC;AAkED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;EAgBjC;AAcD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,CAUxD;AAED,+CAA+C;AAC/C,wBAAgB,aAAa,CAAC,WAAW,EAAE,OAAO,GAAG;IAAE,QAAQ,IAAI,MAAM,CAAA;CAAE,CAgB1E;AAED,mFAAmF;AACnF,8BAAsB,SAAS;IAC7B,QAAQ;CAGT;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;;EAMpC"}
|
|
@@ -148,26 +148,31 @@ function rawMemoryUsage() {
|
|
|
148
148
|
* `arrayBuffers` should allow tracking WASM memory, since every instance backs its
|
|
149
149
|
* memory with `ArrayBuffer`.
|
|
150
150
|
*/
|
|
151
|
-
export function memoryUsage() {
|
|
151
|
+
export function memoryUsage(withDetails) {
|
|
152
152
|
const m = rawMemoryUsage();
|
|
153
153
|
if (m === null) {
|
|
154
154
|
return "";
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
if (withDetails) {
|
|
157
|
+
return `rss=${toMb(m.rss)}MB heap=${toMb(m.heapUsed)}/${toMb(m.heapTotal)}MB external=${toMb(m.external)}MB arrayBuffers=${toMb(m.arrayBuffers)}MB`;
|
|
158
|
+
}
|
|
159
|
+
return `rss=${toMb(m.rss)}MB heap=${toMb(m.heapUsed)}/${toMb(m.heapTotal)}MB`;
|
|
157
160
|
}
|
|
158
161
|
/** Create a stateful memory usage reporter. */
|
|
159
|
-
export function memoryTracker() {
|
|
162
|
+
export function memoryTracker(withDetails) {
|
|
160
163
|
let prev = null;
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
return {
|
|
165
|
+
toString() {
|
|
166
|
+
const m = rawMemoryUsage();
|
|
167
|
+
if (m === null) {
|
|
168
|
+
return "";
|
|
169
|
+
}
|
|
170
|
+
const delta = prev === null || withDetails === false
|
|
171
|
+
? ""
|
|
172
|
+
: ` (Δrss=${signedMb(m.rss - prev.rss)}MB ΔarrayBuffers=${signedMb(m.arrayBuffers - prev.arrayBuffers)}MB)`;
|
|
173
|
+
prev = m;
|
|
174
|
+
return `${memoryUsage(withDetails)}${delta}`;
|
|
175
|
+
},
|
|
171
176
|
};
|
|
172
177
|
}
|
|
173
178
|
/** A class that adds `toString` method that prints all properties of an object. */
|
|
@@ -25,21 +25,27 @@ describe("utils::lazyInspect", () => {
|
|
|
25
25
|
});
|
|
26
26
|
describe("utils::memoryUsage", () => {
|
|
27
27
|
it("should report all memory fields", () => {
|
|
28
|
-
const usage = memoryUsage();
|
|
28
|
+
const usage = memoryUsage(true);
|
|
29
29
|
for (const field of ["rss=", "heap=", "external=", "arrayBuffers="]) {
|
|
30
30
|
assert.ok(usage.includes(field), `expected "${field}" in "${usage}"`);
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
|
+
it("should report all memory fields without details", () => {
|
|
34
|
+
const usage = memoryUsage(false);
|
|
35
|
+
for (const field of ["rss=", "heap="]) {
|
|
36
|
+
assert.ok(usage.includes(field), `expected "${field}" in "${usage}"`);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
33
39
|
});
|
|
34
40
|
describe("utils::memoryTracker", () => {
|
|
35
41
|
it("should not include a delta on the first call", () => {
|
|
36
|
-
const tracker = memoryTracker();
|
|
37
|
-
assert.ok(!tracker().includes("Δrss"));
|
|
42
|
+
const tracker = memoryTracker(true);
|
|
43
|
+
assert.ok(!tracker.toString().includes("Δrss"));
|
|
38
44
|
});
|
|
39
45
|
it("should include a delta on subsequent calls", () => {
|
|
40
|
-
const tracker = memoryTracker();
|
|
41
|
-
tracker();
|
|
42
|
-
const second = tracker();
|
|
46
|
+
const tracker = memoryTracker(true);
|
|
47
|
+
tracker.toString();
|
|
48
|
+
const second = tracker.toString();
|
|
43
49
|
assert.ok(second.includes("Δrss="), `expected delta in "${second}"`);
|
|
44
50
|
assert.ok(second.includes("ΔarrayBuffers="), `expected delta in "${second}"`);
|
|
45
51
|
});
|
|
@@ -4,7 +4,8 @@ import { type FromJson } from "#@typeberry/json-parser";
|
|
|
4
4
|
import { AuthorshipOptions } from "./authorship.js";
|
|
5
5
|
import { JipChainSpec } from "./jip-chain-spec.js";
|
|
6
6
|
/** Development config. Will accept unsealed blocks for now. */
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const DEV_TINY_CONFIG = "dev";
|
|
8
|
+
export declare const DEV_FULL_CONFIG = "dev-full";
|
|
8
9
|
/** Default config file. */
|
|
9
10
|
export declare const DEFAULT_CONFIG = "default";
|
|
10
11
|
export declare const NODE_DEFAULTS: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-config.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/config-node/node-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAuB,MAAM,wBAAwB,CAAC;AAG5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,+DAA+D;AAC/D,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"node-config.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/config-node/node-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAuB,MAAM,wBAAwB,CAAC;AAG5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,+DAA+D;AAC/D,eAAO,MAAM,eAAe,QAAQ,CAAC;AACrC,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C,2BAA2B;AAC3B,eAAO,MAAM,cAAc,YAAY,CAAC;AAExC,eAAO,MAAM,aAAa;;;;CAIzB,CAAC;AAEF,0BAA0B;AAC1B,oBAAY,cAAc;IACxB,uBAAuB;IACvB,IAAI,SAAS;IACb,uBAAuB;IACvB,IAAI,SAAS;CACd;AAED,eAAO,MAAM,sBAAsB,EAS7B,QAAQ,CAAC,cAAc,CAAC,CAAC;AAE/B,qBAAa,iBAAiB;aAqBV,OAAO,EAAE,MAAM;aACf,OAAO,EAAE,MAAM;aACf,MAAM,EAAE,cAAc;aACtB,SAAS,EAAE,YAAY;IACvC,iEAAiE;aACjD,gBAAgB,EAAE,MAAM,GAAG,SAAS;aACpC,UAAU,EAAE,iBAAiB;IA1B/C,MAAM,CAAC,QAAQ,kFAUb;IAEF,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,EAAE,UAAU,CAAC,iBAAiB,CAAC;IAOlH,OAAO;CASR;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,iBAAiB,CAuDlG"}
|
|
@@ -9,7 +9,8 @@ import { AuthorshipOptions } from "./authorship.js";
|
|
|
9
9
|
import { JipChainSpec } from "./jip-chain-spec.js";
|
|
10
10
|
const logger = Logger.new(import.meta.filename, "config");
|
|
11
11
|
/** Development config. Will accept unsealed blocks for now. */
|
|
12
|
-
export const
|
|
12
|
+
export const DEV_TINY_CONFIG = "dev";
|
|
13
|
+
export const DEV_FULL_CONFIG = "dev-full";
|
|
13
14
|
/** Default config file. */
|
|
14
15
|
export const DEFAULT_CONFIG = "default";
|
|
15
16
|
export const NODE_DEFAULTS = {
|
|
@@ -72,8 +73,12 @@ export function loadConfig(config, withRelPath) {
|
|
|
72
73
|
let mergedJson = {};
|
|
73
74
|
for (const entry of config) {
|
|
74
75
|
logger.log `🔧 Applying '${entry}'`;
|
|
75
|
-
if (entry ===
|
|
76
|
-
mergedJson = structuredClone(configs.
|
|
76
|
+
if (entry === DEV_TINY_CONFIG) {
|
|
77
|
+
mergedJson = structuredClone(configs.devTiny); // clone to avoid mutating the original config. not doing a merge since dev and default should theoretically replace all properties.
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (entry === DEV_FULL_CONFIG) {
|
|
81
|
+
mergedJson = structuredClone(configs.devFull); // clone to avoid mutating the original config. not doing a merge since dev and default should theoretically replace all properties.
|
|
77
82
|
continue;
|
|
78
83
|
}
|
|
79
84
|
if (entry === DEFAULT_CONFIG) {
|
|
@@ -70,7 +70,7 @@ describe("loadConfig", () => {
|
|
|
70
70
|
});
|
|
71
71
|
it("should load dev config", () => {
|
|
72
72
|
const config = loadConfig(["dev"], withRelPath);
|
|
73
|
-
assert.deepStrictEqual(config, parseFromJson(configs.
|
|
73
|
+
assert.deepStrictEqual(config, parseFromJson(configs.devTiny, NodeConfiguration.fromJson));
|
|
74
74
|
});
|
|
75
75
|
it("should parse inline json config and deep merge onto previous entries", () => {
|
|
76
76
|
const config = loadConfig(["default", JSON.stringify({ database_base_path: "/test/path", chain_spec: { bootnodes: [] } })], withRelPath);
|
|
@@ -138,9 +138,9 @@ describe("loadConfig", () => {
|
|
|
138
138
|
`.database_base_path="/test/path-1"`,
|
|
139
139
|
], withRelPath);
|
|
140
140
|
assert.deepStrictEqual(config, parseFromJson({
|
|
141
|
-
...configs.
|
|
141
|
+
...configs.devTiny,
|
|
142
142
|
database_base_path: "/test/path-1",
|
|
143
|
-
chain_spec: { ...configs.
|
|
143
|
+
chain_spec: { ...configs.devTiny.chain_spec, bootnodes: [] },
|
|
144
144
|
}, NodeConfiguration.fromJson));
|
|
145
145
|
});
|
|
146
146
|
it("should throw an error if an invalid json file is provided", () => {
|
|
@@ -5,30 +5,67 @@ import type { Blake2b } from "#@typeberry/hash";
|
|
|
5
5
|
import type { ServicesUpdate, State } from "#@typeberry/state";
|
|
6
6
|
import { SerializedState, type StateEntries } from "#@typeberry/state-merkleization";
|
|
7
7
|
import { OK, Result } from "#@typeberry/utils";
|
|
8
|
+
import { type FjallRootOptions, type Partition } from "./root.js";
|
|
9
|
+
/**
|
|
10
|
+
* One open fjall keyspace together with its content-addressed `values`
|
|
11
|
+
* partition.
|
|
12
|
+
*
|
|
13
|
+
* Opening the keyspace is the slow part, so the fuzz target opens one session
|
|
14
|
+
* per run and reuses it for every reset (see `HybridSerializedStates.fromSession`).
|
|
15
|
+
* The values partition is immutable - the key is the hash of the value - so it
|
|
16
|
+
* is fine that values pile up across resets, the unreferenced ones just sit
|
|
17
|
+
* there unused.
|
|
18
|
+
*/
|
|
19
|
+
export declare class FjallValuesSession {
|
|
20
|
+
private readonly root;
|
|
21
|
+
/** Shared content-addressed values partition, reused across resets. */
|
|
22
|
+
readonly values: Partition;
|
|
23
|
+
private constructor();
|
|
24
|
+
/** Open (or create) the keyspace at `dbPath` and its `values` partition. */
|
|
25
|
+
static open(dbPath: string, options?: FjallRootOptions): Promise<FjallValuesSession>;
|
|
26
|
+
/** Flush the journal to disk (a no-op for ephemeral keyspaces). */
|
|
27
|
+
persist(): Promise<void>;
|
|
28
|
+
/** Size of the keyspace directory on disk, in bytes. */
|
|
29
|
+
sizeInBytes(): number | null;
|
|
30
|
+
/** Release the keyspace handle (skips the sync-all fsync when ephemeral). */
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
}
|
|
8
33
|
/**
|
|
9
34
|
* Hybrid serialized-states db (fjall variant).
|
|
10
35
|
*
|
|
11
|
-
* States (leafs) are kept in
|
|
12
|
-
* Reads
|
|
13
|
-
*
|
|
36
|
+
* States (leafs) are kept in memory, only the large values go to fjall on disk.
|
|
37
|
+
* Reads hit fjall directly, which keeps its own bounded block cache. Meant for
|
|
38
|
+
* long fuzzing, used together with pruning so the heap stays bounded.
|
|
14
39
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* because fjall has no transaction primitive.
|
|
40
|
+
* Construction is async, and value writes are flushed explicitly, because fjall
|
|
41
|
+
* has no transaction primitive.
|
|
18
42
|
*/
|
|
19
43
|
export declare class HybridSerializedStates implements StatesDb<SerializedState<LeafDb>>, InitStatesDb<StateEntries> {
|
|
20
44
|
private readonly spec;
|
|
21
45
|
private readonly blake2b;
|
|
22
|
-
private readonly
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
private readonly session;
|
|
47
|
+
/** Whether `close()` should close the underlying session. */
|
|
48
|
+
private readonly ownsSession;
|
|
49
|
+
static new({ spec, blake2b, dbPath, ephemeral, cacheSizeBytes, }: {
|
|
25
50
|
spec: ChainSpec;
|
|
26
51
|
blake2b: Blake2b;
|
|
27
52
|
dbPath: string;
|
|
28
53
|
ephemeral?: boolean;
|
|
54
|
+
cacheSizeBytes?: number;
|
|
29
55
|
}): Promise<HybridSerializedStates>;
|
|
56
|
+
/**
|
|
57
|
+
* Wrap an already-open `FjallValuesSession` and reuse its keyspace.
|
|
58
|
+
*
|
|
59
|
+
* The new instance starts with its own empty in-memory leaf sets but shares
|
|
60
|
+
* the values partition on disk. Its `close()` does not close the session, the
|
|
61
|
+
* session owner closes it once. The fuzz target uses this to keep one keyspace
|
|
62
|
+
* across resets and only rebuild the in-memory state for each vector.
|
|
63
|
+
*/
|
|
64
|
+
static fromSession(spec: ChainSpec, blake2b: Blake2b, session: FjallValuesSession): HybridSerializedStates;
|
|
30
65
|
private readonly inMemStates;
|
|
31
66
|
private readonly valuesDb;
|
|
67
|
+
/** Shared content-addressed values partition (owned by `session`). */
|
|
68
|
+
private readonly values;
|
|
32
69
|
private constructor();
|
|
33
70
|
insertInitialState(headerHash: HeaderHash, entries: StateEntries): Promise<Result<OK, StateUpdateError>>;
|
|
34
71
|
updateAndSetState(header: HeaderHash, state: SerializedState<LeafDb>, update: Partial<State & ServicesUpdate>): Promise<Result<OK, StateUpdateError>>;
|
|
@@ -37,7 +74,7 @@ export declare class HybridSerializedStates implements StatesDb<SerializedState<
|
|
|
37
74
|
markUnused(header: HeaderHash): void;
|
|
38
75
|
diskSizeInBytes(): number | null;
|
|
39
76
|
close(): Promise<void>;
|
|
40
|
-
/** Write new large values to fjall, then flush. */
|
|
77
|
+
/** Write new large values to fjall in a single batch, then flush. */
|
|
41
78
|
private writeValues;
|
|
42
79
|
/** Read a value from fjall. */
|
|
43
80
|
private readValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid-states.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/hybrid-states.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,KAAK,YAAY,EACjB,MAAM,EACN,KAAK,QAAQ,EACb,gBAAgB,EAGjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,KAAK,YAAY,EAGlB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"hybrid-states.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/hybrid-states.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,35 +6,88 @@ import { leafComparator } from "#@typeberry/trie";
|
|
|
6
6
|
import { OK, Result } from "#@typeberry/utils";
|
|
7
7
|
import { FjallRoot, toUint8Array } from "./root.js";
|
|
8
8
|
const logger = Logger.new(import.meta.filename, "db");
|
|
9
|
+
/**
|
|
10
|
+
* One open fjall keyspace together with its content-addressed `values`
|
|
11
|
+
* partition.
|
|
12
|
+
*
|
|
13
|
+
* Opening the keyspace is the slow part, so the fuzz target opens one session
|
|
14
|
+
* per run and reuses it for every reset (see `HybridSerializedStates.fromSession`).
|
|
15
|
+
* The values partition is immutable - the key is the hash of the value - so it
|
|
16
|
+
* is fine that values pile up across resets, the unreferenced ones just sit
|
|
17
|
+
* there unused.
|
|
18
|
+
*/
|
|
19
|
+
export class FjallValuesSession {
|
|
20
|
+
root;
|
|
21
|
+
values;
|
|
22
|
+
constructor(root,
|
|
23
|
+
/** Shared content-addressed values partition, reused across resets. */
|
|
24
|
+
values) {
|
|
25
|
+
this.root = root;
|
|
26
|
+
this.values = values;
|
|
27
|
+
}
|
|
28
|
+
/** Open (or create) the keyspace at `dbPath` and its `values` partition. */
|
|
29
|
+
static async open(dbPath, options = {}) {
|
|
30
|
+
const root = await FjallRoot.open(dbPath, options);
|
|
31
|
+
const values = await root.partition("values");
|
|
32
|
+
return new FjallValuesSession(root, values);
|
|
33
|
+
}
|
|
34
|
+
/** Flush the journal to disk (a no-op for ephemeral keyspaces). */
|
|
35
|
+
async persist() {
|
|
36
|
+
await this.root.persist();
|
|
37
|
+
}
|
|
38
|
+
/** Size of the keyspace directory on disk, in bytes. */
|
|
39
|
+
sizeInBytes() {
|
|
40
|
+
return this.root.sizeInBytes();
|
|
41
|
+
}
|
|
42
|
+
/** Release the keyspace handle (skips the sync-all fsync when ephemeral). */
|
|
43
|
+
async close() {
|
|
44
|
+
await this.root.close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
9
47
|
/**
|
|
10
48
|
* Hybrid serialized-states db (fjall variant).
|
|
11
49
|
*
|
|
12
|
-
* States (leafs) are kept in
|
|
13
|
-
* Reads
|
|
14
|
-
*
|
|
50
|
+
* States (leafs) are kept in memory, only the large values go to fjall on disk.
|
|
51
|
+
* Reads hit fjall directly, which keeps its own bounded block cache. Meant for
|
|
52
|
+
* long fuzzing, used together with pruning so the heap stays bounded.
|
|
15
53
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* because fjall has no transaction primitive.
|
|
54
|
+
* Construction is async, and value writes are flushed explicitly, because fjall
|
|
55
|
+
* has no transaction primitive.
|
|
19
56
|
*/
|
|
20
57
|
export class HybridSerializedStates {
|
|
21
58
|
spec;
|
|
22
59
|
blake2b;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
static async new({ spec, blake2b, dbPath, ephemeral, }) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
return new HybridSerializedStates(spec, blake2b,
|
|
60
|
+
session;
|
|
61
|
+
ownsSession;
|
|
62
|
+
static async new({ spec, blake2b, dbPath, ephemeral, cacheSizeBytes, }) {
|
|
63
|
+
const session = await FjallValuesSession.open(dbPath, { ephemeral, cacheSizeBytes });
|
|
64
|
+
// This instance owns the session it just opened, so its `close()` closes it.
|
|
65
|
+
return new HybridSerializedStates(spec, blake2b, session, true);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Wrap an already-open `FjallValuesSession` and reuse its keyspace.
|
|
69
|
+
*
|
|
70
|
+
* The new instance starts with its own empty in-memory leaf sets but shares
|
|
71
|
+
* the values partition on disk. Its `close()` does not close the session, the
|
|
72
|
+
* session owner closes it once. The fuzz target uses this to keep one keyspace
|
|
73
|
+
* across resets and only rebuild the in-memory state for each vector.
|
|
74
|
+
*/
|
|
75
|
+
static fromSession(spec, blake2b, session) {
|
|
76
|
+
return new HybridSerializedStates(spec, blake2b, session, false);
|
|
29
77
|
}
|
|
30
78
|
inMemStates = HashDictionary.new();
|
|
31
79
|
// A single shared values accessor reused by every `LeafDb` we hand out.
|
|
32
80
|
valuesDb;
|
|
33
|
-
|
|
81
|
+
/** Shared content-addressed values partition (owned by `session`). */
|
|
82
|
+
values;
|
|
83
|
+
constructor(spec, blake2b, session,
|
|
84
|
+
/** Whether `close()` should close the underlying session. */
|
|
85
|
+
ownsSession) {
|
|
34
86
|
this.spec = spec;
|
|
35
87
|
this.blake2b = blake2b;
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
88
|
+
this.session = session;
|
|
89
|
+
this.ownsSession = ownsSession;
|
|
90
|
+
this.values = session.values;
|
|
38
91
|
this.valuesDb = { get: (key) => this.readValue(key) };
|
|
39
92
|
}
|
|
40
93
|
async insertInitialState(headerHash, entries) {
|
|
@@ -80,21 +133,24 @@ export class HybridSerializedStates {
|
|
|
80
133
|
this.inMemStates.delete(header);
|
|
81
134
|
}
|
|
82
135
|
diskSizeInBytes() {
|
|
83
|
-
return this.
|
|
136
|
+
return this.session.sizeInBytes();
|
|
84
137
|
}
|
|
85
138
|
async close() {
|
|
86
|
-
|
|
139
|
+
// Instances backed by a shared session (fuzz reset reuse) keep the keyspace
|
|
140
|
+
// open for the next reset. The session owner closes it once.
|
|
141
|
+
if (this.ownsSession) {
|
|
142
|
+
await this.session.close();
|
|
143
|
+
}
|
|
87
144
|
}
|
|
88
|
-
/** Write new large values to fjall, then flush. */
|
|
145
|
+
/** Write new large values to fjall in a single batch, then flush. */
|
|
89
146
|
async writeValues(values) {
|
|
90
147
|
if (values.length === 0) {
|
|
91
148
|
return Result.ok(OK);
|
|
92
149
|
}
|
|
93
150
|
try {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
await this.root.persist();
|
|
151
|
+
const entries = values.map(([hash, val]) => ({ key: hash.raw, value: val.raw }));
|
|
152
|
+
await this.values.insertBatch(entries);
|
|
153
|
+
await this.session.persist();
|
|
98
154
|
}
|
|
99
155
|
catch (e) {
|
|
100
156
|
logger.error `${e}`;
|
|
@@ -7,7 +7,7 @@ import { Blake2b, HASH_SIZE } from "#@typeberry/hash";
|
|
|
7
7
|
import { InMemoryState } from "#@typeberry/state";
|
|
8
8
|
import { StateEntries } from "#@typeberry/state-merkleization";
|
|
9
9
|
import { deepEqual, OK, Result } from "#@typeberry/utils";
|
|
10
|
-
import { HybridSerializedStates } from "./hybrid-states.js";
|
|
10
|
+
import { FjallValuesSession, HybridSerializedStates } from "./hybrid-states.js";
|
|
11
11
|
let blake2b;
|
|
12
12
|
before(async () => {
|
|
13
13
|
blake2b = await Blake2b.createHasher();
|
|
@@ -66,6 +66,36 @@ describe("Fjall hybrid serialized states", () => {
|
|
|
66
66
|
await states.close();
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
|
+
it("shares an open values session across resets without closing it", async () => {
|
|
70
|
+
// The fuzz reset path opens the values keyspace once per session and reuses
|
|
71
|
+
// it: each "reset" builds a fresh states instance sharing that session, and
|
|
72
|
+
// closing a session-backed states must NOT close the shared keyspace.
|
|
73
|
+
const session = await FjallValuesSession.open(dbPath);
|
|
74
|
+
try {
|
|
75
|
+
const big = BytesBlob.blobFromString("z".repeat(100));
|
|
76
|
+
const key = Bytes.fill(HASH_SIZE, 7).asOpaque();
|
|
77
|
+
const entries = StateEntries.fromEntriesUnsafe([[key, big]]);
|
|
78
|
+
// First "reset": write values through a states instance, then close it.
|
|
79
|
+
const first = HybridSerializedStates.fromSession(spec, blake2b, session);
|
|
80
|
+
const res = await first.insertInitialState(headerHash, entries);
|
|
81
|
+
deepEqual(res, Result.ok(OK));
|
|
82
|
+
await first.close();
|
|
83
|
+
// Second "reset": a fresh states sharing the same session. Its in-memory
|
|
84
|
+
// leaf set is independent (empty until it inserts)...
|
|
85
|
+
const second = HybridSerializedStates.fromSession(spec, blake2b, session);
|
|
86
|
+
assert.strictEqual(second.getState(headerHash), null);
|
|
87
|
+
// ...but the on-disk values store is the same one, still open and usable
|
|
88
|
+
// (a closed keyspace would throw here).
|
|
89
|
+
await second.insertInitialState(headerHash, entries);
|
|
90
|
+
const state = second.getState(headerHash);
|
|
91
|
+
assert.ok(state !== null);
|
|
92
|
+
assert.strictEqual(`${state.backend.get(key)}`, `${big}`);
|
|
93
|
+
await second.close();
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await session.close();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
69
99
|
it("drops the leaf set on markUnused while values stay on disk", async () => {
|
|
70
100
|
const states = await HybridSerializedStates.new({ spec, blake2b, dbPath });
|
|
71
101
|
try {
|
|
@@ -6,20 +6,26 @@ export type { Partition };
|
|
|
6
6
|
export declare function toUint8Array(value: Buffer | null): Uint8Array | null;
|
|
7
7
|
export type FjallRootOptions = {
|
|
8
8
|
/**
|
|
9
|
-
* When set, durability
|
|
9
|
+
* When set, we skip the durability flush (`persist`) and `close()` does not
|
|
10
|
+
* do the sync-all fsync.
|
|
10
11
|
*
|
|
11
|
-
* Only safe for throwaway databases
|
|
12
|
-
*
|
|
12
|
+
* Only safe for throwaway databases, like the fuzz target that wipes on every
|
|
13
|
+
* reset.
|
|
13
14
|
*/
|
|
14
15
|
ephemeral?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Cache size in bytes, shared by all partitions of the keyspace. fjall reads
|
|
18
|
+
* through this cache, so it bounds how much we keep in memory. When not set,
|
|
19
|
+
* fjall uses its own default.
|
|
20
|
+
*/
|
|
21
|
+
cacheSizeBytes?: number;
|
|
15
22
|
};
|
|
16
23
|
/**
|
|
17
|
-
*
|
|
24
|
+
* Thin wrapper over the fjall keyspace.
|
|
18
25
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* of that.
|
|
26
|
+
* fjall is an LSM-tree: it reads and writes through normal file i/o and keeps
|
|
27
|
+
* only a bounded block cache in memory, so the resident set stays bounded even
|
|
28
|
+
* when the store on disk is big.
|
|
23
29
|
*/
|
|
24
30
|
export declare class FjallRoot {
|
|
25
31
|
private readonly keyspace;
|
|
@@ -39,11 +45,11 @@ export declare class FjallRoot {
|
|
|
39
45
|
*/
|
|
40
46
|
persist(): Promise<void>;
|
|
41
47
|
/**
|
|
42
|
-
*
|
|
48
|
+
* Size of the keyspace directory on disk, in bytes.
|
|
43
49
|
*
|
|
44
|
-
* Returns `null`
|
|
45
|
-
*
|
|
46
|
-
*
|
|
50
|
+
* Returns `null` when the directory cannot be walked (e.g. not created yet).
|
|
51
|
+
* A fjall keyspace is a directory of partition and journal files, so we sum
|
|
52
|
+
* them recursively.
|
|
47
53
|
*/
|
|
48
54
|
sizeInBytes(): number | null;
|
|
49
55
|
/** Persist with `sync-all` and release the keyspace handle. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/root.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtE,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,CAKpE;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/database-fjall/root.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtE,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,CAKpE;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,qBAAa,SAAS;IAElB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,+EAA+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO;IAOP,2DAA2D;WAC9C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC;IAUhF,wDAAwD;IAClD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIjD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;;;;OAMG;IACH,WAAW,IAAI,MAAM,GAAG,IAAI;IAQ5B,+DAA+D;IACzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -11,12 +11,11 @@ export function toUint8Array(value) {
|
|
|
11
11
|
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Thin wrapper over the fjall keyspace.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* of that.
|
|
16
|
+
* fjall is an LSM-tree: it reads and writes through normal file i/o and keeps
|
|
17
|
+
* only a bounded block cache in memory, so the resident set stays bounded even
|
|
18
|
+
* when the store on disk is big.
|
|
20
19
|
*/
|
|
21
20
|
export class FjallRoot {
|
|
22
21
|
keyspace;
|
|
@@ -31,7 +30,12 @@ export class FjallRoot {
|
|
|
31
30
|
}
|
|
32
31
|
/** Open (or create) a fjall keyspace at the given path. */
|
|
33
32
|
static async open(dbPath, options) {
|
|
34
|
-
|
|
33
|
+
// Forward our options to the binding: `ephemeral` makes `close()` skip the
|
|
34
|
+
// sync-all fsync, `cacheSizeBytes` bounds how much we keep in memory.
|
|
35
|
+
const keyspace = await open(dbPath, {
|
|
36
|
+
ephemeral: options.ephemeral,
|
|
37
|
+
cacheSizeBytes: options.cacheSizeBytes,
|
|
38
|
+
});
|
|
35
39
|
return new FjallRoot(keyspace, dbPath, options);
|
|
36
40
|
}
|
|
37
41
|
/** Open (or create) a partition under this keyspace. */
|
|
@@ -51,11 +55,11 @@ export class FjallRoot {
|
|
|
51
55
|
await this.keyspace.persist();
|
|
52
56
|
}
|
|
53
57
|
/**
|
|
54
|
-
*
|
|
58
|
+
* Size of the keyspace directory on disk, in bytes.
|
|
55
59
|
*
|
|
56
|
-
* Returns `null`
|
|
57
|
-
*
|
|
58
|
-
*
|
|
60
|
+
* Returns `null` when the directory cannot be walked (e.g. not created yet).
|
|
61
|
+
* A fjall keyspace is a directory of partition and journal files, so we sum
|
|
62
|
+
* them recursively.
|
|
59
63
|
*/
|
|
60
64
|
sizeInBytes() {
|
|
61
65
|
try {
|
|
@@ -108,7 +108,7 @@ export class TicketDistributionTask {
|
|
|
108
108
|
// Wrap with Promise.resolve().then() so a synchronous throw inside the validator
|
|
109
109
|
// funnels into the same .catch() as an async rejection.
|
|
110
110
|
Promise.resolve()
|
|
111
|
-
.then(() => validator.validate(epochIndex, ticket))
|
|
111
|
+
.then(() => validator.validate(epochIndex, [ticket]))
|
|
112
112
|
.then((result) => {
|
|
113
113
|
if (result.isOk) {
|
|
114
114
|
this.addTicket(epochIndex, ticket);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main-fuzz.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-fuzz.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAOrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uBAAuB,EAAE,OAAO,CAAC;CAClC,CAAC;
|
|
1
|
+
{"version":3,"file":"main-fuzz.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-fuzz.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAOrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uBAAuB,EAAE,OAAO,CAAC;CAClC,CAAC;AAoBF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CASpF;AAED,iFAAiF;AACjF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAgB,cAAc;;;;EAM7B;AAED,wBAAsB,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,uBAuJxF"}
|