@typeberry/lib 0.8.4-faebc7a → 0.9.0-c9f9e4d
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/jamnp-s/tasks/ticket-distribution.js +1 -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/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", () => {
|
|
@@ -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);
|
|
@@ -27,7 +27,27 @@ declare function generateSeal(bandersnatch: BandernsatchWasm, authorKey: Banders
|
|
|
27
27
|
export type VrfOutputHash = Opaque<OpaqueHash, "VRF Output Hash">;
|
|
28
28
|
declare function getVrfOutputHash(bandersnatch: BandernsatchWasm, authorKey: BandersnatchSecretSeed, input: BytesBlob): Promise<Result<VrfOutputHash, null>>;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Batch-generate signed tickets for multiple validators in a single native call,
|
|
31
|
+
* reusing the ring prover setup across all of them. Returns one ticket list per
|
|
32
|
+
* validator, in the same order as `proverKeyIndices`/`secrets`.
|
|
31
33
|
*/
|
|
32
|
-
declare function generateTickets(bandersnatch: BandernsatchWasm, ringKeys: BandersnatchKey[],
|
|
34
|
+
declare function generateTickets(bandersnatch: BandernsatchWasm, ringKeys: BandersnatchKey[], proverKeyIndices: readonly number[], secrets: readonly BandersnatchSecretSeed[], entropy: EntropyHash, ticketsPerValidator: number): Promise<Result<SignedTicket[][], null>>;
|
|
35
|
+
/**
|
|
36
|
+
* Build the concatenated ring-VRF inputs for ticket generation: one
|
|
37
|
+
* `JAM_TICKET_SEAL || entropy || attempt_byte` input per attempt.
|
|
38
|
+
*
|
|
39
|
+
* Exposed so the worker-pool path can build the same inputs to hand off to a
|
|
40
|
+
* worker thread without re-deriving the layout.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildTicketVrfInputs(entropy: EntropyHash, ticketsPerValidator: number): {
|
|
43
|
+
inputsData: Uint8Array;
|
|
44
|
+
vrfInputDataLen: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Parse the raw output of `batchGenerateRingVrfForValidators` into per-validator
|
|
48
|
+
* ticket lists. Records are ordered validator-major, then attempt-major; each
|
|
49
|
+
* record is `status byte || signature`. A malformed batch yields a single error
|
|
50
|
+
* byte. Exposed so the worker-pool path can parse a worker's raw result.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseTicketsBatchOutput(result: Uint8Array, numValidators: number, ticketsPerValidator: number): Result<SignedTicket[][], null>;
|
|
33
53
|
//# sourceMappingURL=bandersnatch-vrf.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bandersnatch-vrf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-vrf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAsB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"bandersnatch-vrf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-vrf.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SignedTicket, tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
|
|
2
2
|
import { Bytes, BytesBlob } from "#@typeberry/bytes";
|
|
3
|
+
import { SEED_SIZE } from "#@typeberry/crypto";
|
|
3
4
|
import { BANDERSNATCH_PROOF_BYTES, BANDERSNATCH_RING_ROOT_BYTES, BANDERSNATCH_VRF_SIGNATURE_BYTES, } from "#@typeberry/crypto/bandersnatch.js";
|
|
4
5
|
import { HASH_SIZE } from "#@typeberry/hash";
|
|
5
6
|
import { Result } from "#@typeberry/utils";
|
|
@@ -33,6 +34,10 @@ const ringCommitmentCache = [
|
|
|
33
34
|
keys: BytesBlob.empty(),
|
|
34
35
|
value: Promise.resolve(Result.error(null, () => "")),
|
|
35
36
|
},
|
|
37
|
+
{
|
|
38
|
+
keys: BytesBlob.empty(),
|
|
39
|
+
value: Promise.resolve(Result.error(null, () => "")),
|
|
40
|
+
},
|
|
36
41
|
];
|
|
37
42
|
const FUNCTIONS = {
|
|
38
43
|
verifySeal,
|
|
@@ -122,31 +127,60 @@ async function getVrfOutputHash(bandersnatch, authorKey, input) {
|
|
|
122
127
|
// One byte for result discriminator and the rest is the ring VRF signature.
|
|
123
128
|
const GENERATE_RESULT_ENTRY_LENGTH = 1 + BANDERSNATCH_PROOF_BYTES;
|
|
124
129
|
/**
|
|
125
|
-
*
|
|
130
|
+
* Batch-generate signed tickets for multiple validators in a single native call,
|
|
131
|
+
* reusing the ring prover setup across all of them. Returns one ticket list per
|
|
132
|
+
* validator, in the same order as `proverKeyIndices`/`secrets`.
|
|
126
133
|
*/
|
|
127
|
-
async function generateTickets(bandersnatch, ringKeys,
|
|
128
|
-
|
|
134
|
+
async function generateTickets(bandersnatch, ringKeys, proverKeyIndices, secrets, entropy, ticketsPerValidator) {
|
|
135
|
+
if (proverKeyIndices.length !== secrets.length) {
|
|
136
|
+
return Result.error(null, () => "proverKeyIndices and secrets must have the same length");
|
|
137
|
+
}
|
|
138
|
+
if (proverKeyIndices.length === 0) {
|
|
139
|
+
return Result.ok([]);
|
|
140
|
+
}
|
|
141
|
+
const { inputsData, vrfInputDataLen } = buildTicketVrfInputs(entropy, ticketsPerValidator);
|
|
142
|
+
const ringKeysData = BytesBlob.blobFromParts(ringKeys.map((k) => k.raw)).raw;
|
|
143
|
+
const secretSeedsData = BytesBlob.blobFromParts(secrets.map((s) => s.raw)).raw;
|
|
144
|
+
const result = await bandersnatch.batchGenerateRingVrfForValidators(ringKeysData, Uint32Array.from(proverKeyIndices), secretSeedsData, SEED_SIZE, inputsData, vrfInputDataLen);
|
|
145
|
+
return parseTicketsBatchOutput(result, proverKeyIndices.length, ticketsPerValidator);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build the concatenated ring-VRF inputs for ticket generation: one
|
|
149
|
+
* `JAM_TICKET_SEAL || entropy || attempt_byte` input per attempt.
|
|
150
|
+
*
|
|
151
|
+
* Exposed so the worker-pool path can build the same inputs to hand off to a
|
|
152
|
+
* worker thread without re-deriving the layout.
|
|
153
|
+
*/
|
|
154
|
+
export function buildTicketVrfInputs(entropy, ticketsPerValidator) {
|
|
129
155
|
const vrfInputParts = [];
|
|
130
156
|
for (let attempt = 0; attempt < ticketsPerValidator; attempt++) {
|
|
131
157
|
vrfInputParts.push(BytesBlob.blobFromParts([JAM_TICKET_SEAL, entropy.raw, Uint8Array.of(attempt)]).raw);
|
|
132
158
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
159
|
+
return {
|
|
160
|
+
inputsData: BytesBlob.blobFromParts(vrfInputParts).raw,
|
|
161
|
+
vrfInputDataLen: JAM_TICKET_SEAL.length + entropy.length + 1,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Parse the raw output of `batchGenerateRingVrfForValidators` into per-validator
|
|
166
|
+
* ticket lists. Records are ordered validator-major, then attempt-major; each
|
|
167
|
+
* record is `status byte || signature`. A malformed batch yields a single error
|
|
168
|
+
* byte. Exposed so the worker-pool path can parse a worker's raw result.
|
|
169
|
+
*/
|
|
170
|
+
export function parseTicketsBatchOutput(result, numValidators, ticketsPerValidator) {
|
|
171
|
+
const perValidator = [];
|
|
172
|
+
let offset = 0;
|
|
173
|
+
for (let v = 0; v < numValidators; v++) {
|
|
174
|
+
const tickets = [];
|
|
175
|
+
for (let attempt = 0; attempt < ticketsPerValidator; attempt++) {
|
|
176
|
+
if (result[offset] === ResultValues.Error) {
|
|
177
|
+
return Result.error(null, () => `Ring VRF proof generation failed for validator ${v}, attempt ${attempt}`);
|
|
178
|
+
}
|
|
179
|
+
const signature = Bytes.fromBlob(result.subarray(offset + 1, offset + GENERATE_RESULT_ENTRY_LENGTH), BANDERSNATCH_PROOF_BYTES).asOpaque();
|
|
180
|
+
tickets.push(SignedTicket.create({ attempt: tryAsTicketAttempt(attempt), signature }));
|
|
181
|
+
offset += GENERATE_RESULT_ENTRY_LENGTH;
|
|
144
182
|
}
|
|
145
|
-
|
|
146
|
-
tickets.push(SignedTicket.create({
|
|
147
|
-
attempt: tryAsTicketAttempt(attempt),
|
|
148
|
-
signature,
|
|
149
|
-
}));
|
|
183
|
+
perValidator.push(tickets);
|
|
150
184
|
}
|
|
151
|
-
return Result.ok(
|
|
185
|
+
return Result.ok(perValidator);
|
|
152
186
|
}
|
|
@@ -165,11 +165,12 @@ describe("Bandersnatch verification", () => {
|
|
|
165
165
|
const ringKeys = secrets.map((secret) => deriveBandersnatchPublicKey(secret));
|
|
166
166
|
const proverIndex = 0;
|
|
167
167
|
const entropy = Bytes.fill(HASH_SIZE, 123).asOpaque();
|
|
168
|
-
const genResult = await bandersnatchVrf.generateTickets(await bandersnatchWasm, ringKeys, proverIndex, secrets[proverIndex], entropy, 2);
|
|
168
|
+
const genResult = await bandersnatchVrf.generateTickets(await bandersnatchWasm, ringKeys, [proverIndex], [secrets[proverIndex]], entropy, 2);
|
|
169
169
|
assert.ok(genResult.isOk);
|
|
170
170
|
const commitment = await bandersnatchVrf.getRingCommitment(await bandersnatchWasm, ringKeys);
|
|
171
171
|
assert.ok(commitment.isOk);
|
|
172
|
-
|
|
172
|
+
assert.strictEqual(genResult.ok.length, 1);
|
|
173
|
+
const verifyResult = await bandersnatchVrf.verifyTickets(await bandersnatchWasm, ringKeys.length, commitment.ok, genResult.ok[0], entropy);
|
|
173
174
|
assert.ok(verifyResult.isValid, "Generated tickets should pass verification");
|
|
174
175
|
});
|
|
175
176
|
});
|
|
@@ -8,5 +8,15 @@ export declare class BandernsatchWasm {
|
|
|
8
8
|
generateSeal(authorKey: Uint8Array, input: Uint8Array, auxData: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
9
9
|
getVrfOutputHash(authorKey: Uint8Array, input: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
10
10
|
batchGenerateRingVrf(ringKeys: Uint8Array, proverKeyIndex: number, secretSeed: Uint8Array, inputsData: Uint8Array, vrfInputDataLen: number): Promise<Uint8Array<ArrayBufferLike>>;
|
|
11
|
+
/**
|
|
12
|
+
* Batch-generate ring VRF tickets for multiple validators in a single call,
|
|
13
|
+
* reusing the ring prover setup across all of them.
|
|
14
|
+
*
|
|
15
|
+
* `secretSeedsData` is the fixed-width concatenation of the validators' secret
|
|
16
|
+
* seeds (each `secretSeedDataLen` bytes); `proverKeyIndices` are their indices
|
|
17
|
+
* within the ring and must have the same count. Output records are ordered
|
|
18
|
+
* validator-major then input-major, each `status byte || signature`.
|
|
19
|
+
*/
|
|
20
|
+
batchGenerateRingVrfForValidators(ringKeys: Uint8Array, proverKeyIndices: Uint32Array, secretSeedsData: Uint8Array, secretSeedDataLen: number, inputsData: Uint8Array, vrfInputDataLen: number): Promise<Uint8Array<ArrayBufferLike>>;
|
|
11
21
|
}
|
|
12
22
|
//# sourceMappingURL=bandersnatch-wasm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bandersnatch-wasm.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-wasm.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,OAAO;WAEM,GAAG;IAKV,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAIjG,iBAAiB,CACrB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,UAAU,EAC7B,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,EACvB,oBAAoB,EAAE,UAAU;IAY5B,iBAAiB,CAAC,IAAI,EAAE,UAAU;IAIlC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM;IAI1G,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAI1E,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;IAIzD,oBAAoB,CACxB,QAAQ,EAAE,UAAU,EACpB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"bandersnatch-wasm.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-wasm.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,OAAO;WAEM,GAAG;IAKV,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAIjG,iBAAiB,CACrB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,UAAU,EAC7B,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,EACvB,oBAAoB,EAAE,UAAU;IAY5B,iBAAiB,CAAC,IAAI,EAAE,UAAU;IAIlC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM;IAI1G,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAI1E,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;IAIzD,oBAAoB,CACxB,QAAQ,EAAE,UAAU,EACpB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,MAAM;IAKzB;;;;;;;;OAQG;IACG,iCAAiC,CACrC,QAAQ,EAAE,UAAU,EACpB,gBAAgB,EAAE,WAAW,EAC7B,eAAe,EAAE,UAAU,EAC3B,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,MAAM;CAW1B"}
|
|
@@ -26,4 +26,16 @@ export class BandernsatchWasm {
|
|
|
26
26
|
async batchGenerateRingVrf(ringKeys, proverKeyIndex, secretSeed, inputsData, vrfInputDataLen) {
|
|
27
27
|
return bandersnatchWasm.batchGenerateRingVrf(ringKeys, proverKeyIndex, secretSeed, inputsData, vrfInputDataLen);
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Batch-generate ring VRF tickets for multiple validators in a single call,
|
|
31
|
+
* reusing the ring prover setup across all of them.
|
|
32
|
+
*
|
|
33
|
+
* `secretSeedsData` is the fixed-width concatenation of the validators' secret
|
|
34
|
+
* seeds (each `secretSeedDataLen` bytes); `proverKeyIndices` are their indices
|
|
35
|
+
* within the ring and must have the same count. Output records are ordered
|
|
36
|
+
* validator-major then input-major, each `status byte || signature`.
|
|
37
|
+
*/
|
|
38
|
+
async batchGenerateRingVrfForValidators(ringKeys, proverKeyIndices, secretSeedsData, secretSeedDataLen, inputsData, vrfInputDataLen) {
|
|
39
|
+
return bandersnatchWasm.batchGenerateRingVrfForValidators(ringKeys, proverKeyIndices, secretSeedsData, secretSeedDataLen, inputsData, vrfInputDataLen);
|
|
40
|
+
}
|
|
29
41
|
}
|
|
@@ -9,7 +9,8 @@ import { Result } from "#@typeberry/utils";
|
|
|
9
9
|
* it delegates to another process that doesn't bother to send the id back over the wire.
|
|
10
10
|
*/
|
|
11
11
|
export type ValidatedTicket = {
|
|
12
|
-
|
|
12
|
+
ticket: SignedTicket;
|
|
13
|
+
id: EntropyHash;
|
|
13
14
|
};
|
|
14
15
|
/** Reasons a ticket may fail validation. */
|
|
15
16
|
export declare enum ValidationError {
|
|
@@ -27,20 +28,20 @@ export declare enum ValidationError {
|
|
|
27
28
|
* worker via IPC, or short-circuit (Accept/Deny defaults for tests).
|
|
28
29
|
*/
|
|
29
30
|
export interface TicketValidator {
|
|
30
|
-
validate(epochIndex: Epoch,
|
|
31
|
+
validate(epochIndex: Epoch, tickets: SignedTicket[]): Promise<Result<ValidatedTicket[], ValidationError>>;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* Accepts every ticket without inspection. Useful for unit tests where the validator
|
|
34
35
|
* isn't the subject under test. Must never be used in production.
|
|
35
36
|
*/
|
|
36
37
|
export declare class AcceptTicketsValidator implements TicketValidator {
|
|
37
|
-
validate(_epochIndex: Epoch,
|
|
38
|
+
validate(_epochIndex: Epoch, ticket: SignedTicket[]): Promise<Result<ValidatedTicket[], ValidationError>>;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Rejects every ticket. Used as the default for any task that needs an explicit, real
|
|
41
42
|
* validator wired in before it will accept anything from the network.
|
|
42
43
|
*/
|
|
43
44
|
export declare class DenyTicketsValidator implements TicketValidator {
|
|
44
|
-
validate(_epochIndex: Epoch,
|
|
45
|
+
validate(_epochIndex: Epoch, _tickets: SignedTicket[]): Promise<Result<ValidatedTicket[], ValidationError>>;
|
|
45
46
|
}
|
|
46
47
|
//# sourceMappingURL=ticket-validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket-validator.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/ticket-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"ticket-validator.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/ticket-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,EAAE,EAAE,WAAW,CAAC;CACjB,CAAC;AAEF,4CAA4C;AAC5C,oBAAY,eAAe;IACzB,+CAA+C;IAC/C,YAAY,kBAAkB;IAC9B,oFAAoF;IACpF,oBAAoB,0BAA0B;IAC9C,yEAAyE;IACzE,UAAU,gBAAgB;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;CAC3G;AAED;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IACtD,QAAQ,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,eAAe,CAAC,CAAC;CAQhH;AAED;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IACpD,QAAQ,CAAC,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,eAAe,CAAC,CAAC;CAGlH"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Bytes } from "#@typeberry/bytes";
|
|
2
|
+
import { HASH_SIZE } from "#@typeberry/hash";
|
|
1
3
|
import { Result } from "#@typeberry/utils";
|
|
2
4
|
/** Reasons a ticket may fail validation. */
|
|
3
5
|
export var ValidationError;
|
|
@@ -14,8 +16,11 @@ export var ValidationError;
|
|
|
14
16
|
* isn't the subject under test. Must never be used in production.
|
|
15
17
|
*/
|
|
16
18
|
export class AcceptTicketsValidator {
|
|
17
|
-
async validate(_epochIndex,
|
|
18
|
-
return Result.ok(
|
|
19
|
+
async validate(_epochIndex, ticket) {
|
|
20
|
+
return Result.ok(ticket.map((ticket) => ({
|
|
21
|
+
ticket,
|
|
22
|
+
id: Bytes.zero(HASH_SIZE).asOpaque(),
|
|
23
|
+
})));
|
|
19
24
|
}
|
|
20
25
|
}
|
|
21
26
|
/**
|
|
@@ -23,7 +28,7 @@ export class AcceptTicketsValidator {
|
|
|
23
28
|
* validator wired in before it will accept anything from the network.
|
|
24
29
|
*/
|
|
25
30
|
export class DenyTicketsValidator {
|
|
26
|
-
async validate(_epochIndex,
|
|
31
|
+
async validate(_epochIndex, _tickets) {
|
|
27
32
|
return Result.error(ValidationError.ValidatorUnavailable, () => "no ticket validator wired");
|
|
28
33
|
}
|
|
29
34
|
}
|
|
@@ -4,6 +4,7 @@ import { tryAsEpoch } from "#@typeberry/block";
|
|
|
4
4
|
import { SignedTicket, tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
|
|
5
5
|
import { Bytes } from "#@typeberry/bytes";
|
|
6
6
|
import { BANDERSNATCH_PROOF_BYTES } from "#@typeberry/crypto";
|
|
7
|
+
import { HASH_SIZE } from "#@typeberry/hash";
|
|
7
8
|
import { AcceptTicketsValidator, DenyTicketsValidator, ValidationError } from "./ticket-validator.js";
|
|
8
9
|
const E1 = tryAsEpoch(1);
|
|
9
10
|
function makeTicket() {
|
|
@@ -13,19 +14,19 @@ function makeTicket() {
|
|
|
13
14
|
});
|
|
14
15
|
}
|
|
15
16
|
describe("AcceptTicketsValidator", () => {
|
|
16
|
-
it("returns ok with
|
|
17
|
+
it("returns ok with zero id", async () => {
|
|
17
18
|
const v = new AcceptTicketsValidator();
|
|
18
|
-
const res = await v.validate(E1, makeTicket());
|
|
19
|
+
const res = await v.validate(E1, [makeTicket()]);
|
|
19
20
|
assert.strictEqual(res.isOk, true);
|
|
20
21
|
if (res.isOk) {
|
|
21
|
-
assert.strictEqual(res.ok.id,
|
|
22
|
+
assert.strictEqual(res.ok[0].id.toString(), Bytes.zero(HASH_SIZE).toString());
|
|
22
23
|
}
|
|
23
24
|
});
|
|
24
25
|
});
|
|
25
26
|
describe("DenyTicketsValidator", () => {
|
|
26
27
|
it("returns ValidatorUnavailable", async () => {
|
|
27
28
|
const v = new DenyTicketsValidator();
|
|
28
|
-
const res = await v.validate(E1, makeTicket());
|
|
29
|
+
const res = await v.validate(E1, [makeTicket()]);
|
|
29
30
|
assert.strictEqual(res.isError, true);
|
|
30
31
|
if (res.isError) {
|
|
31
32
|
assert.strictEqual(res.error, ValidationError.ValidatorUnavailable);
|
|
@@ -16,6 +16,8 @@ export type VerifiedTicket = {
|
|
|
16
16
|
export declare class VerifiedTicketPool {
|
|
17
17
|
private readonly perEpoch;
|
|
18
18
|
private readonly idSets;
|
|
19
|
+
static new(): VerifiedTicketPool;
|
|
20
|
+
private constructor();
|
|
19
21
|
/** Add pre-verified tickets to the pool, deduping by id. */
|
|
20
22
|
add(epochIndex: Epoch, verifiedTickets: readonly VerifiedTicket[]): void;
|
|
21
23
|
/** Returns the verified tickets for the given epoch, or an empty array if none. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verified-ticket-pool.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/verified-ticket-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,yFAAyF;AACzF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,EAAE,EAAE,WAAW,CAAC;CACjB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAEjE,4DAA4D;IAC5D,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAoBxE,mFAAmF;IACnF,WAAW,CAAC,UAAU,EAAE,KAAK,GAAG,SAAS,cAAc,EAAE;CAG1D"}
|
|
1
|
+
{"version":3,"file":"verified-ticket-pool.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/verified-ticket-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,yFAAyF;AACzF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,EAAE,EAAE,WAAW,CAAC;CACjB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAEjE,MAAM,CAAC,GAAG;IAIV,OAAO;IAEP,4DAA4D;IAC5D,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAoBxE,mFAAmF;IACnF,WAAW,CAAC,UAAU,EAAE,KAAK,GAAG,SAAS,cAAc,EAAE;CAG1D"}
|
|
@@ -10,6 +10,10 @@ import { HashSet } from "#@typeberry/collections/hash-set.js";
|
|
|
10
10
|
export class VerifiedTicketPool {
|
|
11
11
|
perEpoch = new Map();
|
|
12
12
|
idSets = new Map();
|
|
13
|
+
static new() {
|
|
14
|
+
return new VerifiedTicketPool();
|
|
15
|
+
}
|
|
16
|
+
constructor() { }
|
|
13
17
|
/** Add pre-verified tickets to the pool, deduping by id. */
|
|
14
18
|
add(epochIndex, verifiedTickets) {
|
|
15
19
|
if (this.perEpoch.size > 0 && !this.perEpoch.has(epochIndex)) {
|
|
@@ -21,17 +21,17 @@ function makeId(byte) {
|
|
|
21
21
|
}
|
|
22
22
|
describe("VerifiedTicketPool", () => {
|
|
23
23
|
it("starts empty", () => {
|
|
24
|
-
const pool = new
|
|
24
|
+
const pool = VerifiedTicketPool.new();
|
|
25
25
|
assert.deepStrictEqual(pool.getForEpoch(E1), []);
|
|
26
26
|
});
|
|
27
27
|
it("adds and retrieves tickets per epoch", () => {
|
|
28
|
-
const pool = new
|
|
28
|
+
const pool = VerifiedTicketPool.new();
|
|
29
29
|
pool.add(E1, [{ ticket: makeTicket(1), id: makeId(0xaa) }]);
|
|
30
30
|
assert.strictEqual(pool.getForEpoch(E1).length, 1);
|
|
31
31
|
assert.deepStrictEqual(pool.getForEpoch(E2), []);
|
|
32
32
|
});
|
|
33
33
|
it("dedups by id", () => {
|
|
34
|
-
const pool = new
|
|
34
|
+
const pool = VerifiedTicketPool.new();
|
|
35
35
|
const id = makeId(0x01);
|
|
36
36
|
pool.add(E1, [{ ticket: makeTicket(1), id }]);
|
|
37
37
|
pool.add(E1, [{ ticket: makeTicket(2), id }]);
|
|
@@ -39,14 +39,14 @@ describe("VerifiedTicketPool", () => {
|
|
|
39
39
|
assert.strictEqual(pool.getForEpoch(E1)[0].ticket.signature.raw[0], 1);
|
|
40
40
|
});
|
|
41
41
|
it("clears previous epochs when a new epoch is added", () => {
|
|
42
|
-
const pool = new
|
|
42
|
+
const pool = VerifiedTicketPool.new();
|
|
43
43
|
pool.add(E1, [{ ticket: makeTicket(1), id: makeId(1) }]);
|
|
44
44
|
pool.add(E2, [{ ticket: makeTicket(2), id: makeId(2) }]);
|
|
45
45
|
assert.deepStrictEqual(pool.getForEpoch(E1), []);
|
|
46
46
|
assert.strictEqual(pool.getForEpoch(E2).length, 1);
|
|
47
47
|
});
|
|
48
48
|
it("appends across multiple add() calls for the same epoch", () => {
|
|
49
|
-
const pool = new
|
|
49
|
+
const pool = VerifiedTicketPool.new();
|
|
50
50
|
pool.add(E1, [{ ticket: makeTicket(1), id: makeId(1) }]);
|
|
51
51
|
pool.add(E1, [{ ticket: makeTicket(2), id: makeId(2) }]);
|
|
52
52
|
assert.strictEqual(pool.getForEpoch(E1).length, 2);
|