@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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Transferable } from "node:worker_threads";
|
|
2
|
+
/**
|
|
3
|
+
* Parameters for a single ticket-generation shard sent to a worker thread.
|
|
4
|
+
*/
|
|
5
|
+
export declare class TicketGenShardParams {
|
|
6
|
+
/** Concatenated ring public keys (`ringSize * 32` bytes). */
|
|
7
|
+
readonly ringKeysData: Uint8Array;
|
|
8
|
+
/** Index within the ring for each validator in this shard. */
|
|
9
|
+
readonly proverKeyIndices: Uint32Array;
|
|
10
|
+
/** Concatenated validator secret seeds (`count * secretSeedDataLen` bytes). */
|
|
11
|
+
readonly secretSeedsData: Uint8Array;
|
|
12
|
+
/** Length of each secret seed in `secretSeedsData`. */
|
|
13
|
+
readonly secretSeedDataLen: number;
|
|
14
|
+
/** Concatenated VRF inputs, one per attempt. */
|
|
15
|
+
readonly inputsData: Uint8Array;
|
|
16
|
+
/** Length of each VRF input in `inputsData`. */
|
|
17
|
+
readonly vrfInputDataLen: number;
|
|
18
|
+
constructor(
|
|
19
|
+
/** Concatenated ring public keys (`ringSize * 32` bytes). */
|
|
20
|
+
ringKeysData: Uint8Array,
|
|
21
|
+
/** Index within the ring for each validator in this shard. */
|
|
22
|
+
proverKeyIndices: Uint32Array,
|
|
23
|
+
/** Concatenated validator secret seeds (`count * secretSeedDataLen` bytes). */
|
|
24
|
+
secretSeedsData: Uint8Array,
|
|
25
|
+
/** Length of each secret seed in `secretSeedsData`. */
|
|
26
|
+
secretSeedDataLen: number,
|
|
27
|
+
/** Concatenated VRF inputs, one per attempt. */
|
|
28
|
+
inputsData: Uint8Array,
|
|
29
|
+
/** Length of each VRF input in `inputsData`. */
|
|
30
|
+
vrfInputDataLen: number);
|
|
31
|
+
/**
|
|
32
|
+
* No transfers: `ringKeysData` and `inputsData` are shared across all shards,
|
|
33
|
+
* so transferring would detach them for the other shards.
|
|
34
|
+
*/
|
|
35
|
+
getTransferList(): Transferable[];
|
|
36
|
+
}
|
|
37
|
+
/** Result of a ticket-generation shard: the raw `batchGenerateRingVrfForValidators` output. */
|
|
38
|
+
export declare class TicketGenShardResult {
|
|
39
|
+
/** Raw output: validator-major, attempt-major records of `status || signature`. */
|
|
40
|
+
readonly signatures: Uint8Array;
|
|
41
|
+
constructor(
|
|
42
|
+
/** Raw output: validator-major, attempt-major records of `status || signature`. */
|
|
43
|
+
signatures: Uint8Array);
|
|
44
|
+
/**
|
|
45
|
+
* No transfers: the native binding returns a view backed by external/WASM
|
|
46
|
+
* memory that cannot be detached, so transferring it throws inside the worker.
|
|
47
|
+
*/
|
|
48
|
+
getTransferList(): Transferable[];
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../../../packages/workers/block-authorship/ticket-generator/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,qBAAa,oBAAoB;IAE7B,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,UAAU;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,gBAAgB,EAAE,WAAW;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,EAAE,UAAU;IACpC,uDAAuD;IACvD,QAAQ,CAAC,iBAAiB,EAAE,MAAM;IAClC,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,UAAU;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,eAAe,EAAE,MAAM;;IAXhC,6DAA6D;IACpD,YAAY,EAAE,UAAU;IACjC,8DAA8D;IACrD,gBAAgB,EAAE,WAAW;IACtC,+EAA+E;IACtE,eAAe,EAAE,UAAU;IACpC,uDAAuD;IAC9C,iBAAiB,EAAE,MAAM;IAClC,gDAAgD;IACvC,UAAU,EAAE,UAAU;IAC/B,gDAAgD;IACvC,eAAe,EAAE,MAAM;IAGlC;;;OAGG;IACH,eAAe,IAAI,YAAY,EAAE;CAGlC;AAED,+FAA+F;AAC/F,qBAAa,oBAAoB;IAE7B,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,UAAU;;IAD/B,mFAAmF;IAC1E,UAAU,EAAE,UAAU;IAGjC;;;OAGG;IACH,eAAe,IAAI,YAAY,EAAE;CAGlC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameters for a single ticket-generation shard sent to a worker thread.
|
|
3
|
+
*/
|
|
4
|
+
export class TicketGenShardParams {
|
|
5
|
+
ringKeysData;
|
|
6
|
+
proverKeyIndices;
|
|
7
|
+
secretSeedsData;
|
|
8
|
+
secretSeedDataLen;
|
|
9
|
+
inputsData;
|
|
10
|
+
vrfInputDataLen;
|
|
11
|
+
constructor(
|
|
12
|
+
/** Concatenated ring public keys (`ringSize * 32` bytes). */
|
|
13
|
+
ringKeysData,
|
|
14
|
+
/** Index within the ring for each validator in this shard. */
|
|
15
|
+
proverKeyIndices,
|
|
16
|
+
/** Concatenated validator secret seeds (`count * secretSeedDataLen` bytes). */
|
|
17
|
+
secretSeedsData,
|
|
18
|
+
/** Length of each secret seed in `secretSeedsData`. */
|
|
19
|
+
secretSeedDataLen,
|
|
20
|
+
/** Concatenated VRF inputs, one per attempt. */
|
|
21
|
+
inputsData,
|
|
22
|
+
/** Length of each VRF input in `inputsData`. */
|
|
23
|
+
vrfInputDataLen) {
|
|
24
|
+
this.ringKeysData = ringKeysData;
|
|
25
|
+
this.proverKeyIndices = proverKeyIndices;
|
|
26
|
+
this.secretSeedsData = secretSeedsData;
|
|
27
|
+
this.secretSeedDataLen = secretSeedDataLen;
|
|
28
|
+
this.inputsData = inputsData;
|
|
29
|
+
this.vrfInputDataLen = vrfInputDataLen;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* No transfers: `ringKeysData` and `inputsData` are shared across all shards,
|
|
33
|
+
* so transferring would detach them for the other shards.
|
|
34
|
+
*/
|
|
35
|
+
getTransferList() {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Result of a ticket-generation shard: the raw `batchGenerateRingVrfForValidators` output. */
|
|
40
|
+
export class TicketGenShardResult {
|
|
41
|
+
signatures;
|
|
42
|
+
constructor(
|
|
43
|
+
/** Raw output: validator-major, attempt-major records of `status || signature`. */
|
|
44
|
+
signatures) {
|
|
45
|
+
this.signatures = signatures;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* No transfers: the native binding returns a view backed by external/WASM
|
|
49
|
+
* memory that cannot be detached, so transferring it throws inside the worker.
|
|
50
|
+
*/
|
|
51
|
+
getTransferList() {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -16,6 +16,10 @@ export type ValidatorKey = {
|
|
|
16
16
|
*
|
|
17
17
|
* Each validator key produces `ticketsPerValidator` tickets using ring VRF proofs.
|
|
18
18
|
* The ring keys define the anonymous set - only members can produce valid proofs.
|
|
19
|
+
*
|
|
20
|
+
* All resolved validators are generated in a single batched native call
|
|
21
|
+
* ({@link bandersnatchVrf.generateTickets}) which reuses the ring
|
|
22
|
+
* prover setup across the batch.
|
|
19
23
|
*/
|
|
20
24
|
export declare function generateTickets(bandersnatch: BandernsatchWasm, ringKeys: BandersnatchKey[], validatorKeys: ValidatorKey[], entropy: EntropyHash, ticketsPerValidator: number): Promise<Result<SignedTicket[], TicketGeneratorError>>;
|
|
21
25
|
//# sourceMappingURL=ticket-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-generator.d.ts","sourceRoot":"","sources":["../../../../../../packages/workers/block-authorship/ticket-generator/ticket-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1C,oBAAY,oBAAoB;IAC9B,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,gBAAgB,EAC9B,QAAQ,EAAE,eAAe,EAAE,EAC3B,aAAa,EAAE,YAAY,EAAE,EAC7B,OAAO,EAAE,WAAW,EACpB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,oBAAoB,CAAC,CAAC,CA2CvD"}
|
|
@@ -12,25 +12,35 @@ export var TicketGeneratorError;
|
|
|
12
12
|
*
|
|
13
13
|
* Each validator key produces `ticketsPerValidator` tickets using ring VRF proofs.
|
|
14
14
|
* The ring keys define the anonymous set - only members can produce valid proofs.
|
|
15
|
+
*
|
|
16
|
+
* All resolved validators are generated in a single batched native call
|
|
17
|
+
* ({@link bandersnatchVrf.generateTickets}) which reuses the ring
|
|
18
|
+
* prover setup across the batch.
|
|
15
19
|
*/
|
|
16
20
|
export async function generateTickets(bandersnatch, ringKeys, validatorKeys, entropy, ticketsPerValidator) {
|
|
17
|
-
|
|
21
|
+
// Resolve each validator's index within the ring, skipping any that are not
|
|
22
|
+
// members (only ring members can produce valid proofs).
|
|
23
|
+
const proverKeyIndices = [];
|
|
24
|
+
const secrets = [];
|
|
18
25
|
for (const validatorKey of validatorKeys) {
|
|
19
26
|
const proverIndex = ringKeys.findIndex((k) => k.isEqualTo(validatorKey.public));
|
|
20
27
|
if (proverIndex < 0) {
|
|
21
28
|
logger.warn `Validator public key not found in the ring, skipping ticket generation for this key`;
|
|
22
29
|
continue;
|
|
23
30
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
else
|
|
29
|
-
|
|
31
|
+
proverKeyIndices.push(proverIndex);
|
|
32
|
+
secrets.push(validatorKey.secret);
|
|
33
|
+
}
|
|
34
|
+
if (proverKeyIndices.length === 0) {
|
|
35
|
+
// No resolvable validators: an error if some were requested, else just empty.
|
|
36
|
+
if (validatorKeys.length > 0) {
|
|
37
|
+
return Result.error(TicketGeneratorError.TicketGenerationFailed, () => "Failed to generate tickets for all validators");
|
|
30
38
|
}
|
|
39
|
+
return Result.ok([]);
|
|
31
40
|
}
|
|
32
|
-
|
|
41
|
+
const result = await bandersnatchVrf.generateTickets(bandersnatch, ringKeys, proverKeyIndices, secrets, entropy, ticketsPerValidator);
|
|
42
|
+
if (result.isError) {
|
|
33
43
|
return Result.error(TicketGeneratorError.TicketGenerationFailed, () => "Failed to generate tickets for all validators");
|
|
34
44
|
}
|
|
35
|
-
return Result.ok(
|
|
45
|
+
return Result.ok(result.ok.flat());
|
|
36
46
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-generator.test.d.ts","sourceRoot":"","sources":["../../../../../../packages/workers/block-authorship/ticket-generator/ticket-generator.test.ts"],"names":[],"mappings":""}
|
|
@@ -21,15 +21,19 @@ function createMockValidatorKeys(count) {
|
|
|
21
21
|
describe("Ticket Generator", () => {
|
|
22
22
|
beforeEach(async () => {
|
|
23
23
|
await initWasm();
|
|
24
|
-
mock.method(bandersnatchVrf, "generateTickets", async (_bandersnatch, _ringKeys,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
tickets
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
mock.method(bandersnatchVrf, "generateTickets", async (_bandersnatch, _ringKeys, proverKeyIndices, _secrets, _entropy, ticketsPerValidator) => {
|
|
25
|
+
// One ticket list per resolved validator, in validator-major order.
|
|
26
|
+
const perValidator = proverKeyIndices.map(() => {
|
|
27
|
+
const tickets = [];
|
|
28
|
+
for (let attempt = 0; attempt < ticketsPerValidator; attempt++) {
|
|
29
|
+
tickets.push({
|
|
30
|
+
attempt: tryAsTicketAttempt(attempt),
|
|
31
|
+
signature: Bytes.zero(784).asOpaque(),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return tickets;
|
|
35
|
+
});
|
|
36
|
+
return Result.ok(perValidator);
|
|
33
37
|
});
|
|
34
38
|
});
|
|
35
39
|
afterEach(() => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { EntropyHash } from "#@typeberry/block";
|
|
2
|
+
import type { SignedTicket } from "#@typeberry/block/tickets.js";
|
|
3
|
+
import { type BandersnatchKey } from "#@typeberry/crypto";
|
|
4
|
+
import type { ValidatorKey } from "./ticket-generator.js";
|
|
5
|
+
/**
|
|
6
|
+
* A pool of worker threads that generate ring-VRF tickets in parallel.
|
|
7
|
+
*
|
|
8
|
+
* Ring-VRF proof generation is a heavy, synchronous, CPU-bound native call
|
|
9
|
+
* (~0.7s per validator with a large ring). Running it on the authoring thread
|
|
10
|
+
* blocks block production; this pool shards the work across worker threads so
|
|
11
|
+
* the main thread stays free and wall-clock time drops ~linearly with cores.
|
|
12
|
+
*
|
|
13
|
+
* Uses `Executor` from `@typeberry/concurrent`.
|
|
14
|
+
*/
|
|
15
|
+
export declare class TicketGeneratorPool {
|
|
16
|
+
private readonly executor;
|
|
17
|
+
/** Number of worker threads in the pool. */
|
|
18
|
+
readonly workerCount: number;
|
|
19
|
+
private constructor();
|
|
20
|
+
/** Spawn `workerCount` worker threads (each initialises the native binding). */
|
|
21
|
+
static create(workerCount: number): Promise<TicketGeneratorPool>;
|
|
22
|
+
/** Terminate all worker threads. */
|
|
23
|
+
destroy(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Generate tickets for `validatorKeys`, sharded evenly across the pool.
|
|
26
|
+
*
|
|
27
|
+
* `onShardTickets` is invoked on the calling (main) thread as each shard's
|
|
28
|
+
* results arrive, so tickets can be pooled/distributed incrementally rather
|
|
29
|
+
* than waiting for the whole batch. Returns once every shard has settled.
|
|
30
|
+
*
|
|
31
|
+
* Validators whose public key is not in `ringKeys` are skipped (they cannot
|
|
32
|
+
* produce valid proofs).
|
|
33
|
+
*/
|
|
34
|
+
generate(ringKeys: BandersnatchKey[], validatorKeys: ValidatorKey[], entropy: EntropyHash, ticketsPerValidator: number, onShardTickets: (tickets: SignedTicket[]) => Promise<void>): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=worker-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-pool.d.ts","sourceRoot":"","sources":["../../../../../../packages/workers/block-authorship/ticket-generator/worker-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EAAE,KAAK,eAAe,EAA0C,MAAM,mBAAmB,CAAC;AAIjG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAiB1D;;;;;;;;;GASG;AACH,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,4CAA4C;aAC5B,WAAW,EAAE,MAAM;IAHrC,OAAO;IAMP,gFAAgF;WACnE,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQtE,oCAAoC;IAC9B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;;;;;;;;OASG;IACG,QAAQ,CACZ,QAAQ,EAAE,eAAe,EAAE,EAC3B,aAAa,EAAE,YAAY,EAAE,EAC7B,OAAO,EAAE,WAAW,EACpB,mBAAmB,EAAE,MAAM,EAC3B,cAAc,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC;CA6DjB"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { BytesBlob } from "#@typeberry/bytes";
|
|
2
|
+
import { Executor } from "#@typeberry/concurrent";
|
|
3
|
+
import { SEED_SIZE } from "#@typeberry/crypto";
|
|
4
|
+
import { Logger } from "#@typeberry/logger";
|
|
5
|
+
import { buildTicketVrfInputs, parseTicketsBatchOutput } from "#@typeberry/safrole/bandersnatch-vrf.js";
|
|
6
|
+
import { TicketGenShardParams } from "./protocol.js";
|
|
7
|
+
const logger = Logger.new(import.meta.filename, "tickets-pool");
|
|
8
|
+
/** `.mjs` bootstrap that `tsImport`s the worker entry (worker threads need it under tsx). */
|
|
9
|
+
const WORKER_BOOTSTRAP = new URL("./bootstrap-ticket-generator.mjs", import.meta.url);
|
|
10
|
+
/**
|
|
11
|
+
* Validators per shard.
|
|
12
|
+
*
|
|
13
|
+
* Kept small so tickets stream into the pool incrementally (and get included in
|
|
14
|
+
* blocks throughout the contest period) rather than arriving in one lump when
|
|
15
|
+
* generation finishes. The prover setup is re-done per shard, but that cost is
|
|
16
|
+
* tiny next to the per-proof time, so finer shards add only ~1-2% overhead.
|
|
17
|
+
*/
|
|
18
|
+
const TICKET_SHARD_SIZE = 16;
|
|
19
|
+
/**
|
|
20
|
+
* A pool of worker threads that generate ring-VRF tickets in parallel.
|
|
21
|
+
*
|
|
22
|
+
* Ring-VRF proof generation is a heavy, synchronous, CPU-bound native call
|
|
23
|
+
* (~0.7s per validator with a large ring). Running it on the authoring thread
|
|
24
|
+
* blocks block production; this pool shards the work across worker threads so
|
|
25
|
+
* the main thread stays free and wall-clock time drops ~linearly with cores.
|
|
26
|
+
*
|
|
27
|
+
* Uses `Executor` from `@typeberry/concurrent`.
|
|
28
|
+
*/
|
|
29
|
+
export class TicketGeneratorPool {
|
|
30
|
+
executor;
|
|
31
|
+
workerCount;
|
|
32
|
+
constructor(executor,
|
|
33
|
+
/** Number of worker threads in the pool. */
|
|
34
|
+
workerCount) {
|
|
35
|
+
this.executor = executor;
|
|
36
|
+
this.workerCount = workerCount;
|
|
37
|
+
}
|
|
38
|
+
/** Spawn `workerCount` worker threads (each initialises the native binding). */
|
|
39
|
+
static async create(workerCount) {
|
|
40
|
+
const executor = await Executor.initialize(WORKER_BOOTSTRAP, {
|
|
41
|
+
minWorkers: workerCount,
|
|
42
|
+
maxWorkers: workerCount,
|
|
43
|
+
});
|
|
44
|
+
return new TicketGeneratorPool(executor, workerCount);
|
|
45
|
+
}
|
|
46
|
+
/** Terminate all worker threads. */
|
|
47
|
+
async destroy() {
|
|
48
|
+
await this.executor.destroy();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Generate tickets for `validatorKeys`, sharded evenly across the pool.
|
|
52
|
+
*
|
|
53
|
+
* `onShardTickets` is invoked on the calling (main) thread as each shard's
|
|
54
|
+
* results arrive, so tickets can be pooled/distributed incrementally rather
|
|
55
|
+
* than waiting for the whole batch. Returns once every shard has settled.
|
|
56
|
+
*
|
|
57
|
+
* Validators whose public key is not in `ringKeys` are skipped (they cannot
|
|
58
|
+
* produce valid proofs).
|
|
59
|
+
*/
|
|
60
|
+
async generate(ringKeys, validatorKeys, entropy, ticketsPerValidator, onShardTickets) {
|
|
61
|
+
// Resolve each validator's index within the ring (skip non-members).
|
|
62
|
+
const keyToIndex = new Map();
|
|
63
|
+
for (let i = 0; i < ringKeys.length; i++) {
|
|
64
|
+
keyToIndex.set(ringKeys[i].toString(), i);
|
|
65
|
+
}
|
|
66
|
+
const resolved = [];
|
|
67
|
+
for (const vk of validatorKeys) {
|
|
68
|
+
const idx = keyToIndex.get(vk.public.toString());
|
|
69
|
+
if (idx === undefined) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
resolved.push({ index: idx, secret: vk.secret });
|
|
73
|
+
}
|
|
74
|
+
if (resolved.length === 0) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const { inputsData, vrfInputDataLen } = buildTicketVrfInputs(entropy, ticketsPerValidator);
|
|
78
|
+
const ringKeysData = BytesBlob.blobFromParts(ringKeys.map((k) => k.raw)).raw;
|
|
79
|
+
const runShard = (shard) => {
|
|
80
|
+
const indices = Uint32Array.from(shard.map((r) => r.index));
|
|
81
|
+
const secretSeedsData = BytesBlob.blobFromParts(shard.map((r) => r.secret.raw)).raw;
|
|
82
|
+
const params = new TicketGenShardParams(ringKeysData, indices, secretSeedsData, SEED_SIZE, inputsData, vrfInputDataLen);
|
|
83
|
+
return this.executor
|
|
84
|
+
.run(params)
|
|
85
|
+
.then((result) => {
|
|
86
|
+
const parsed = parseTicketsBatchOutput(result.signatures, indices.length, ticketsPerValidator);
|
|
87
|
+
if (parsed.isError) {
|
|
88
|
+
logger.warn `A ticket-generation shard returned an invalid proof: ${parsed.error}`;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
return onShardTickets(parsed.ok.flat());
|
|
92
|
+
})
|
|
93
|
+
.catch((e) => {
|
|
94
|
+
logger.warn `A ticket-generation shard failed: ${e}`;
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
// Dispatch small shards in waves of `workerCount` so every worker stays busy
|
|
98
|
+
// and tickets are delivered incrementally (one wave at a time) without
|
|
99
|
+
// over-queuing the executor.
|
|
100
|
+
const shardSize = Math.min(resolved.length, TICKET_SHARD_SIZE);
|
|
101
|
+
const waveSize = shardSize * this.workerCount;
|
|
102
|
+
for (let waveStart = 0; waveStart < resolved.length; waveStart += waveSize) {
|
|
103
|
+
const wave = [];
|
|
104
|
+
const waveEnd = Math.min(waveStart + waveSize, resolved.length);
|
|
105
|
+
for (let start = waveStart; start < waveEnd; start += shardSize) {
|
|
106
|
+
wave.push(runShard(resolved.slice(start, start + shardSize)));
|
|
107
|
+
}
|
|
108
|
+
await Promise.all(wave);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -3,23 +3,22 @@ import type { SignedTicket } from "#@typeberry/block/tickets.js";
|
|
|
3
3
|
import type { ChainSpec } from "#@typeberry/config";
|
|
4
4
|
import type { BandernsatchWasm } from "#@typeberry/safrole/bandersnatch-wasm.js";
|
|
5
5
|
import type { State } from "#@typeberry/state";
|
|
6
|
-
import { type TicketValidator,
|
|
6
|
+
import { type TicketValidator, ValidationError, type VerifiedTicket } from "#@typeberry/ticket-pool";
|
|
7
7
|
import { Result } from "#@typeberry/utils";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* commitment and current epoch entropy using bandersnatch
|
|
11
|
-
* ticket (with its computed id) into the supplied {@link VerifiedTicketPool}.
|
|
9
|
+
* {@link TicketValidator} implementation that verifies a ticket against the ring
|
|
10
|
+
* commitment and current epoch entropy using bandersnatch.
|
|
12
11
|
*
|
|
13
12
|
* `getState` is a thunk because state advances continuously while validation is in
|
|
14
13
|
* flight; we want the latest available state for each call.
|
|
15
14
|
*/
|
|
16
15
|
export declare class BandersnatchTicketValidator implements TicketValidator {
|
|
17
|
-
private readonly bandersnatch;
|
|
18
16
|
private readonly chainSpec;
|
|
19
|
-
private readonly
|
|
17
|
+
private readonly bandersnatch;
|
|
20
18
|
private readonly getState;
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
static new(chainSpec: ChainSpec, bandersnatch: BandernsatchWasm, getState: () => State): BandersnatchTicketValidator;
|
|
20
|
+
private constructor();
|
|
21
|
+
validate(epochIndex: Epoch, inTickets: SignedTicket[]): Promise<Result<VerifiedTicket[], ValidationError>>;
|
|
23
22
|
/**
|
|
24
23
|
* Returns the correct tickets entropy for verification given the current state.
|
|
25
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket-validator.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/block-authorship/ticket-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ticket-validator.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/block-authorship/ticket-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACpG,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;;;;GAMG;AACH,qBAAa,2BAA4B,YAAW,eAAe;IAM/D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,KAAK;IAItF,OAAO;IAMD,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,eAAe,CAAC,CAAC;IAwChH;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;CAIzB"}
|
|
@@ -1,46 +1,49 @@
|
|
|
1
|
-
import { Logger } from "#@typeberry/logger";
|
|
2
1
|
import bandersnatchVrf from "#@typeberry/safrole/bandersnatch-vrf.js";
|
|
3
|
-
import { ValidationError
|
|
2
|
+
import { ValidationError } from "#@typeberry/ticket-pool";
|
|
4
3
|
import { Result } from "#@typeberry/utils";
|
|
5
|
-
const logger = Logger.new(import.meta.filename, "ticket-validator");
|
|
6
4
|
/**
|
|
7
|
-
*
|
|
8
|
-
* commitment and current epoch entropy using bandersnatch
|
|
9
|
-
* ticket (with its computed id) into the supplied {@link VerifiedTicketPool}.
|
|
5
|
+
* {@link TicketValidator} implementation that verifies a ticket against the ring
|
|
6
|
+
* commitment and current epoch entropy using bandersnatch.
|
|
10
7
|
*
|
|
11
8
|
* `getState` is a thunk because state advances continuously while validation is in
|
|
12
9
|
* flight; we want the latest available state for each call.
|
|
13
10
|
*/
|
|
14
11
|
export class BandersnatchTicketValidator {
|
|
15
|
-
bandersnatch;
|
|
16
12
|
chainSpec;
|
|
17
|
-
|
|
13
|
+
bandersnatch;
|
|
18
14
|
getState;
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
static new(chainSpec, bandersnatch, getState) {
|
|
16
|
+
return new BandersnatchTicketValidator(chainSpec, bandersnatch, getState);
|
|
17
|
+
}
|
|
18
|
+
constructor(chainSpec, bandersnatch, getState) {
|
|
21
19
|
this.chainSpec = chainSpec;
|
|
22
|
-
this.
|
|
20
|
+
this.bandersnatch = bandersnatch;
|
|
23
21
|
this.getState = getState;
|
|
24
22
|
}
|
|
25
|
-
async validate(epochIndex,
|
|
23
|
+
async validate(epochIndex, inTickets) {
|
|
26
24
|
const state = this.getState();
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
// Reject obviously invalid epochs up front: we only have the entropy to verify
|
|
26
|
+
// the current epoch (tickets being submitted now) and the next one (tickets at
|
|
27
|
+
// an epoch boundary). Anything else would only fail after the expensive proof
|
|
28
|
+
// check, so a peer could otherwise burn CPU with far-past/future batches.
|
|
29
|
+
const stateEpoch = Math.floor(state.timeslot / this.chainSpec.epochLength);
|
|
30
|
+
if (epochIndex < stateEpoch || epochIndex > stateEpoch + 1) {
|
|
31
|
+
return Result.error(ValidationError.InvalidProof, () => `ticket batch targets an invalid epoch ${epochIndex}`);
|
|
29
32
|
}
|
|
30
33
|
const entropy = this.getTicketEntropy(epochIndex, state);
|
|
31
|
-
// Batch verifier: a single `isValid` covers the whole batch
|
|
32
|
-
// computed id per input ticket.
|
|
33
|
-
const { isValid, tickets } = await bandersnatchVrf.verifyTickets(this.bandersnatch, state.designatedValidatorData.length, state.epochRoot,
|
|
34
|
-
if (tickets.length !==
|
|
35
|
-
|
|
36
|
-
return Result.error(ValidationError.ValidatorUnavailable, () => "verifier returned unexpected result count");
|
|
34
|
+
// Batch verifier: a single `isValid` covers the whole batch
|
|
35
|
+
// and `tickets` holds the computed id per input ticket.
|
|
36
|
+
const { isValid, tickets } = await bandersnatchVrf.verifyTickets(this.bandersnatch, state.designatedValidatorData.length, state.epochRoot, inTickets, entropy);
|
|
37
|
+
if (tickets.length !== inTickets.length) {
|
|
38
|
+
return Result.error(ValidationError.ValidatorUnavailable, () => `io size mismatch got: ${tickets.length}, expected ${inTickets.length}`);
|
|
37
39
|
}
|
|
38
40
|
if (!isValid) {
|
|
39
41
|
return Result.error(ValidationError.InvalidProof, () => "bandersnatch proof rejected");
|
|
40
42
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
return Result.ok(inTickets.map((ticket, index) => {
|
|
44
|
+
const id = tickets[index];
|
|
45
|
+
return { ticket, id };
|
|
46
|
+
}));
|
|
44
47
|
}
|
|
45
48
|
/**
|
|
46
49
|
* Returns the correct tickets entropy for verification given the current state.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Api, type Internal } from "#@typeberry/workers-api";
|
|
2
|
-
import {
|
|
2
|
+
import { TicketsMessage } from "./tickets-message.js";
|
|
3
3
|
/**
|
|
4
4
|
* Port name for authorship-network direct communication.
|
|
5
5
|
* Used when spawning jam-network worker to pass the port for receiving tickets.
|
|
@@ -33,12 +33,12 @@ export declare const protocol: import("@typeberry/workers-api").LousyProtocol<{
|
|
|
33
33
|
};
|
|
34
34
|
}, {
|
|
35
35
|
receivedTickets: {
|
|
36
|
-
request: import("@typeberry/codec").Descriptor<
|
|
36
|
+
request: import("@typeberry/codec").Descriptor<TicketsMessage, import("@typeberry/codec").ViewOf<TicketsMessage, {
|
|
37
37
|
epochIndex: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"Epoch">, import("@typeberry/bytes").Bytes<4>>;
|
|
38
|
-
|
|
38
|
+
tickets: import("@typeberry/codec").Descriptor<import("@typeberry/block").SignedTicket[], import("@typeberry/codec").SequenceView<import("@typeberry/block").SignedTicket, import("@typeberry/codec").ViewOf<import("@typeberry/block").SignedTicket, {
|
|
39
39
|
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[u8]">, import("@typeberry/numbers").U32>;
|
|
40
40
|
signature: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<784> & import("@typeberry/utils").WithOpaque<"BandersnatchRingSignature">, import("@typeberry/bytes").Bytes<784>>;
|
|
41
|
-
}
|
|
41
|
+
}>>>;
|
|
42
42
|
}>>;
|
|
43
43
|
response: import("@typeberry/codec").Descriptor<boolean, boolean>;
|
|
44
44
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/comms-authorship-network/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,GAAG,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/comms-authorship-network/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,GAAG,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBnB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC;AACnD,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,QAAQ,CAAC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { codec } from "#@typeberry/codec";
|
|
2
2
|
import { createProtocol } from "#@typeberry/workers-api";
|
|
3
|
-
import {
|
|
3
|
+
import { TicketsMessage } from "./tickets-message.js";
|
|
4
4
|
/**
|
|
5
5
|
* Port name for authorship-network direct communication.
|
|
6
6
|
* Used when spawning jam-network worker to pass the port for receiving tickets.
|
|
@@ -26,12 +26,11 @@ export const protocol = createProtocol("authorship-network", {
|
|
|
26
26
|
response: codec.nothing,
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
|
-
// Messages from jam-network to block-authorship
|
|
30
|
-
// Response indicates whether
|
|
31
|
-
// to decide whether to redistribute the ticket to other peers.
|
|
29
|
+
// Messages from jam-network to block-authorship
|
|
30
|
+
// Response indicates whether all tickets in batch were valid (no per-ticket validity!)
|
|
32
31
|
fromWorker: {
|
|
33
32
|
receivedTickets: {
|
|
34
|
-
request:
|
|
33
|
+
request: TicketsMessage.Codec,
|
|
35
34
|
response: codec.bool,
|
|
36
35
|
},
|
|
37
36
|
},
|
|
@@ -15,18 +15,4 @@ export declare class TicketsMessage extends WithDebug {
|
|
|
15
15
|
static create({ epochIndex, tickets }: CodecRecord<TicketsMessage>): TicketsMessage;
|
|
16
16
|
private constructor();
|
|
17
17
|
}
|
|
18
|
-
/** Single-ticket message sent from jam-network to block-authorship (one ticket per peer relay). */
|
|
19
|
-
export declare class ReceivedTicketMessage extends WithDebug {
|
|
20
|
-
readonly epochIndex: Epoch;
|
|
21
|
-
readonly ticket: SignedTicket;
|
|
22
|
-
static Codec: import("@typeberry/codec").Descriptor<ReceivedTicketMessage, import("@typeberry/codec").ViewOf<ReceivedTicketMessage, {
|
|
23
|
-
epochIndex: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"Epoch">, import("@typeberry/bytes").Bytes<4>>;
|
|
24
|
-
ticket: import("@typeberry/codec").Descriptor<SignedTicket, import("@typeberry/codec").ViewOf<SignedTicket, {
|
|
25
|
-
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[u8]">, import("@typeberry/numbers").U32>;
|
|
26
|
-
signature: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<784> & import("@typeberry/utils").WithOpaque<"BandersnatchRingSignature">, import("@typeberry/bytes").Bytes<784>>;
|
|
27
|
-
}>>;
|
|
28
|
-
}>>;
|
|
29
|
-
static create({ epochIndex, ticket }: CodecRecord<ReceivedTicketMessage>): ReceivedTicketMessage;
|
|
30
|
-
private constructor();
|
|
31
|
-
}
|
|
32
18
|
//# sourceMappingURL=tickets-message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tickets-message.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/comms-authorship-network/tickets-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,KAAK,WAAW,EAAS,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,qBAAa,cAAe,SAAQ,SAAS;aAWzB,UAAU,EAAE,KAAK;aACjB,OAAO,EAAE,YAAY,EAAE;IAXzC,MAAM,CAAC,KAAK;;;;;;QAGT;IAEH,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,WAAW,CAAC,cAAc,CAAC;IAIlE,OAAO;CAMR
|
|
1
|
+
{"version":3,"file":"tickets-message.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/comms-authorship-network/tickets-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,KAAK,WAAW,EAAS,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,qBAAa,cAAe,SAAQ,SAAS;aAWzB,UAAU,EAAE,KAAK;aACjB,OAAO,EAAE,YAAY,EAAE;IAXzC,MAAM,CAAC,KAAK;;;;;;QAGT;IAEH,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,WAAW,CAAC,cAAc,CAAC;IAIlE,OAAO;CAMR"}
|
|
@@ -17,20 +17,3 @@ export class TicketsMessage extends WithDebug {
|
|
|
17
17
|
this.tickets = tickets;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
/** Single-ticket message sent from jam-network to block-authorship (one ticket per peer relay). */
|
|
21
|
-
export class ReceivedTicketMessage extends WithDebug {
|
|
22
|
-
epochIndex;
|
|
23
|
-
ticket;
|
|
24
|
-
static Codec = codec.Class(ReceivedTicketMessage, {
|
|
25
|
-
epochIndex: codec.u32.asOpaque(),
|
|
26
|
-
ticket: SignedTicket.Codec,
|
|
27
|
-
});
|
|
28
|
-
static create({ epochIndex, ticket }) {
|
|
29
|
-
return new ReceivedTicketMessage(epochIndex, ticket);
|
|
30
|
-
}
|
|
31
|
-
constructor(epochIndex, ticket) {
|
|
32
|
-
super();
|
|
33
|
-
this.epochIndex = epochIndex;
|
|
34
|
-
this.ticket = ticket;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -21,7 +21,7 @@ export type ImporterOptions = {
|
|
|
21
21
|
finalizer?: Finalizer;
|
|
22
22
|
pruneBlocks?: boolean;
|
|
23
23
|
};
|
|
24
|
-
/** Construction arguments for
|
|
24
|
+
/** Construction arguments for `Importer`. */
|
|
25
25
|
export type ImporterArgs = {
|
|
26
26
|
spec: ChainSpec;
|
|
27
27
|
pvm: PvmBackend;
|
|
@@ -45,7 +45,7 @@ export declare class Importer {
|
|
|
45
45
|
private readonly options;
|
|
46
46
|
private readonly events;
|
|
47
47
|
/**
|
|
48
|
-
* Build an
|
|
48
|
+
* Build an `Importer` connected to the best state loaded from `states`.
|
|
49
49
|
*
|
|
50
50
|
* Throws if the best state cannot be loaded — callers are expected to treat that
|
|
51
51
|
* as a programmer error (the DB should be initialized before reaching here).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/importer/importer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAiB,MAAM,kBAAkB,CAAC;AACvH,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAiB,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,EAA0B,KAAK,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAC3F,OAAO,EAA6B,MAAM,EAAkB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,KAAK,sBAAsB,EAAiB,MAAM,YAAY,CAAC;AAExE,oBAAY,iBAAiB;IAC3B,QAAQ,IAAI;IACZ,GAAG,IAAI;IACP,MAAM,IAAI;CACX;AAED,MAAM,MAAM,aAAa,GACrB,WAAW,CAAC,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,GAC3D,WAAW,CAAC,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,GAC5C,WAAW,CAAC,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAO5D,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/importer/importer.ts"],"names":[],"mappings":"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"}
|