@typeberry/lib 0.5.7 → 0.5.8-dbdc34c
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 +3 -1
- package/packages/core/utils/debug.d.ts.map +1 -1
- package/packages/core/utils/debug.js +14 -3
- package/packages/jam/block/block.d.ts +3 -3
- package/packages/jam/block/header.d.ts +6 -6
- package/packages/jam/block/test-helpers.d.ts +2 -2
- package/packages/jam/block/tickets.d.ts +5 -4
- package/packages/jam/block/tickets.d.ts.map +1 -1
- package/packages/jam/block/tickets.js +13 -6
- package/packages/jam/block-json/block.d.ts +2 -2
- package/packages/jam/block-json/block.js +1 -1
- package/packages/jam/block-json/common.d.ts +2 -1
- package/packages/jam/block-json/common.d.ts.map +1 -1
- package/packages/jam/block-json/common.js +2 -5
- package/packages/jam/block-json/extrinsic.js +1 -1
- package/packages/jam/block-json/header.d.ts +2 -1
- package/packages/jam/block-json/header.d.ts.map +1 -1
- package/packages/jam/block-json/header.js +34 -32
- package/packages/jam/block-json/tickets-extrinsic.d.ts +2 -1
- package/packages/jam/block-json/tickets-extrinsic.d.ts.map +1 -1
- package/packages/jam/block-json/tickets-extrinsic.js +7 -5
- package/packages/jam/fuzz-proto/v1/types.d.ts +1 -1
- package/packages/jam/jamnp-s/network.d.ts +2 -0
- package/packages/jam/jamnp-s/network.d.ts.map +1 -1
- package/packages/jam/jamnp-s/network.js +4 -0
- package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.d.ts +10 -3
- package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.d.ts.map +1 -1
- package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.js +12 -4
- package/packages/jam/jamnp-s/protocol/ce-131-ce-132-safrole-ticket-distribution.test.js +4 -3
- package/packages/jam/jamnp-s/protocol/up-0-block-announcement.d.ts +1 -1
- package/packages/jam/jamnp-s/tasks/ticket-distribution.d.ts +34 -0
- package/packages/jam/jamnp-s/tasks/ticket-distribution.d.ts.map +1 -0
- package/packages/jam/jamnp-s/tasks/ticket-distribution.js +115 -0
- package/packages/jam/jamnp-s/tasks/ticket-distribution.test.d.ts +2 -0
- package/packages/jam/jamnp-s/tasks/ticket-distribution.test.d.ts.map +1 -0
- package/packages/jam/jamnp-s/tasks/ticket-distribution.test.js +220 -0
- package/packages/jam/node/main.d.ts.map +1 -1
- package/packages/jam/node/main.js +56 -26
- package/packages/jam/node/reader.d.ts +2 -2
- package/packages/jam/node/workers.d.ts +32 -25
- package/packages/jam/node/workers.d.ts.map +1 -1
- package/packages/jam/node/workers.js +16 -7
- package/packages/jam/safrole/bandersnatch-vrf.d.ts +3 -2
- package/packages/jam/safrole/bandersnatch-vrf.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-vrf.js +2 -2
- package/packages/jam/safrole/bandersnatch-vrf.test.js +3 -2
- package/packages/jam/safrole/safrole.test.js +80 -72
- package/packages/jam/state/safrole-data.d.ts +1 -1
- package/packages/jam/state/test.utils.js +1 -1
- package/packages/jam/state-json/dump.js +2 -2
- package/packages/jam/state-json/safrole.d.ts +2 -2
- package/packages/jam/state-json/safrole.d.ts.map +1 -1
- package/packages/jam/state-json/safrole.js +8 -6
- package/packages/jam/state-merkleization/in-memory-state-codec.d.ts +1 -1
- package/packages/jam/state-vectors/index.d.ts +8 -7
- package/packages/jam/state-vectors/index.d.ts.map +1 -1
- package/packages/jam/state-vectors/index.js +6 -4
- package/packages/jam/transition/hasher.test.js +1 -1
- package/packages/workers/api-node/config.d.ts +5 -1
- package/packages/workers/api-node/config.d.ts.map +1 -1
- package/packages/workers/api-node/config.js +9 -3
- package/packages/workers/api-node/port.d.ts +8 -0
- package/packages/workers/api-node/port.d.ts.map +1 -1
- package/packages/workers/api-node/port.js +10 -0
- package/packages/workers/block-authorship/bootstrap-main.js +10 -3
- package/packages/workers/block-authorship/main.d.ts +2 -1
- package/packages/workers/block-authorship/main.d.ts.map +1 -1
- package/packages/workers/block-authorship/main.js +31 -4
- package/packages/workers/block-authorship/protocol.d.ts +4 -4
- package/packages/workers/block-authorship/ticket-generator.d.ts +3 -2
- package/packages/workers/block-authorship/ticket-generator.d.ts.map +1 -1
- package/packages/workers/block-authorship/ticket-generator.js +2 -3
- package/packages/workers/block-authorship/ticket-generator.test.js +11 -10
- package/packages/workers/comms-authorship-network/index.d.ts +3 -0
- package/packages/workers/comms-authorship-network/index.d.ts.map +1 -0
- package/packages/workers/comms-authorship-network/index.js +2 -0
- package/packages/workers/comms-authorship-network/protocol.d.ts +27 -0
- package/packages/workers/comms-authorship-network/protocol.d.ts.map +1 -0
- package/packages/workers/comms-authorship-network/protocol.js +24 -0
- package/packages/workers/comms-authorship-network/tickets-message.d.ts +18 -0
- package/packages/workers/comms-authorship-network/tickets-message.d.ts.map +1 -0
- package/packages/workers/comms-authorship-network/tickets-message.js +19 -0
- package/packages/workers/importer/protocol.d.ts +8 -8
- package/packages/workers/jam-network/bootstrap-main.js +10 -3
- package/packages/workers/jam-network/main.d.ts +2 -1
- package/packages/workers/jam-network/main.d.ts.map +1 -1
- package/packages/workers/jam-network/main.js +8 -1
- package/packages/workers/jam-network/protocol.d.ts +10 -10
|
@@ -3,6 +3,7 @@ import { ChainSpec } from "#@typeberry/config";
|
|
|
3
3
|
import { type BlocksDb, type RootDb, type SerializedStatesDb } from "#@typeberry/database";
|
|
4
4
|
import { Blake2b } from "#@typeberry/hash";
|
|
5
5
|
import type { WorkerConfig } from "#@typeberry/workers-api";
|
|
6
|
+
import { ThreadPort, type TransferablePort } from "./port.js";
|
|
6
7
|
/** A worker config that's usable in node.js and uses LMDB database backend. */
|
|
7
8
|
export declare class LmdbWorkerConfig<T = void> implements WorkerConfig<T, BlocksDb, SerializedStatesDb> {
|
|
8
9
|
readonly nodeName: string;
|
|
@@ -10,12 +11,14 @@ export declare class LmdbWorkerConfig<T = void> implements WorkerConfig<T, Block
|
|
|
10
11
|
readonly workerParams: T;
|
|
11
12
|
readonly dbPath: string;
|
|
12
13
|
readonly blake2b: Blake2b;
|
|
13
|
-
|
|
14
|
+
readonly ports: Map<string, ThreadPort>;
|
|
15
|
+
static new<T>({ nodeName, chainSpec, workerParams, dbPath, blake2b, ports, }: {
|
|
14
16
|
nodeName: string;
|
|
15
17
|
chainSpec: ChainSpec;
|
|
16
18
|
workerParams: T;
|
|
17
19
|
dbPath: string;
|
|
18
20
|
blake2b: Blake2b;
|
|
21
|
+
ports?: Map<string, ThreadPort>;
|
|
19
22
|
}): LmdbWorkerConfig<T>;
|
|
20
23
|
/** Restore node config from a transferable config object. */
|
|
21
24
|
static fromTransferable<T>(decodeParams: Decode<T>, config: TransferableConfig): Promise<LmdbWorkerConfig<T>>;
|
|
@@ -32,6 +35,7 @@ export type TransferableConfig = {
|
|
|
32
35
|
chainSpec: ChainSpec;
|
|
33
36
|
workerParams: Uint8Array;
|
|
34
37
|
dbPath: string;
|
|
38
|
+
workerPorts: [string, TransferablePort][];
|
|
35
39
|
};
|
|
36
40
|
/**
|
|
37
41
|
* In-memory (direct) worker using serialized state database.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAW,KAAK,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,KAAK,QAAQ,EAGb,KAAK,MAAM,EACX,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAW,KAAK,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,KAAK,QAAQ,EAGb,KAAK,MAAM,EACX,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE9D,+EAA+E;AAC/E,qBAAa,gBAAgB,CAAC,CAAC,GAAG,IAAI,CAAE,YAAW,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,CAAC;aAuC5E,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,SAAS;aACpB,YAAY,EAAE,CAAC;aACf,MAAM,EAAE,MAAM;aACd,OAAO,EAAE,OAAO;aAChB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IA3ChD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EACZ,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,MAAM,EACN,OAAO,EACP,KAAiB,GAClB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,YAAY,EAAE,CAAC,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KACjC;IAID,6DAA6D;WAChD,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,kBAAkB;IAkBpF,OAAO;IASP,YAAY,CAAC,OAAO,GAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAuB,GAAG,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IAUvG,6DAA6D;IAC7D,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAS7D;AAED,6DAA6D;AAC7D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,UAAU,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,qBAAa,iBAAiB,CAAC,CAAC,GAAG,SAAS,CAAE,YAAW,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,CAAC;aAmBlF,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,SAAS;aACpB,YAAY,EAAE,CAAC;aACf,OAAO,EAAE,OAAO;IArBlC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EACZ,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,OAAO,GACR,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,YAAY,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB;IAID,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAElD,OAAO;IAUP,YAAY,CAAC,QAAQ,GAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAuB,GAAG,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CAQzG"}
|
|
@@ -3,6 +3,7 @@ import { ChainSpec } from "#@typeberry/config";
|
|
|
3
3
|
import { InMemoryBlocks, InMemorySerializedStates, } from "#@typeberry/database";
|
|
4
4
|
import { LmdbBlocks, LmdbRoot, LmdbStates } from "#@typeberry/database-lmdb";
|
|
5
5
|
import { Blake2b } from "#@typeberry/hash";
|
|
6
|
+
import { ThreadPort } from "./port.js";
|
|
6
7
|
/** A worker config that's usable in node.js and uses LMDB database backend. */
|
|
7
8
|
export class LmdbWorkerConfig {
|
|
8
9
|
nodeName;
|
|
@@ -10,28 +11,32 @@ export class LmdbWorkerConfig {
|
|
|
10
11
|
workerParams;
|
|
11
12
|
dbPath;
|
|
12
13
|
blake2b;
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
ports;
|
|
15
|
+
static new({ nodeName, chainSpec, workerParams, dbPath, blake2b, ports = new Map(), }) {
|
|
16
|
+
return new LmdbWorkerConfig(nodeName, chainSpec, workerParams, dbPath, blake2b, ports);
|
|
15
17
|
}
|
|
16
18
|
/** Restore node config from a transferable config object. */
|
|
17
19
|
static async fromTransferable(decodeParams, config) {
|
|
18
20
|
const blake2b = await Blake2b.createHasher();
|
|
19
21
|
const chainSpec = new ChainSpec(config.chainSpec);
|
|
20
22
|
const workerParams = Decoder.decodeObject(decodeParams, config.workerParams, chainSpec);
|
|
23
|
+
const ports = new Map(config.workerPorts.map(([name, port]) => [name, ThreadPort.fromTransferable(chainSpec, port)]));
|
|
21
24
|
return LmdbWorkerConfig.new({
|
|
22
25
|
nodeName: config.nodeName,
|
|
23
26
|
chainSpec,
|
|
24
27
|
workerParams,
|
|
25
28
|
dbPath: config.dbPath,
|
|
26
29
|
blake2b,
|
|
30
|
+
ports,
|
|
27
31
|
});
|
|
28
32
|
}
|
|
29
|
-
constructor(nodeName, chainSpec, workerParams, dbPath, blake2b) {
|
|
33
|
+
constructor(nodeName, chainSpec, workerParams, dbPath, blake2b, ports) {
|
|
30
34
|
this.nodeName = nodeName;
|
|
31
35
|
this.chainSpec = chainSpec;
|
|
32
36
|
this.workerParams = workerParams;
|
|
33
37
|
this.dbPath = dbPath;
|
|
34
38
|
this.blake2b = blake2b;
|
|
39
|
+
this.ports = ports;
|
|
35
40
|
}
|
|
36
41
|
openDatabase(options = { readonly: true }) {
|
|
37
42
|
const lmdb = new LmdbRoot(this.dbPath, options.readonly);
|
|
@@ -48,6 +53,7 @@ export class LmdbWorkerConfig {
|
|
|
48
53
|
chainSpec: this.chainSpec,
|
|
49
54
|
workerParams: Encoder.encodeObject(paramsCodec, this.workerParams, this.chainSpec).raw,
|
|
50
55
|
dbPath: this.dbPath,
|
|
56
|
+
workerPorts: Array.from(this.ports.entries()).map(([name, port]) => [name, port.intoTransferable()]),
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
59
|
}
|
|
@@ -7,12 +7,20 @@ export type Message = {
|
|
|
7
7
|
responseId: string;
|
|
8
8
|
data: Uint8Array;
|
|
9
9
|
};
|
|
10
|
+
/** Transferable representation of a `ThreadPort`. */
|
|
11
|
+
export type TransferablePort = {
|
|
12
|
+
threadId: number;
|
|
13
|
+
port: MessagePort;
|
|
14
|
+
};
|
|
10
15
|
export declare class ThreadPort implements Port {
|
|
11
16
|
private readonly spec;
|
|
12
17
|
private readonly port;
|
|
18
|
+
static pair(spec: ChainSpec): [ThreadPort, ThreadPort];
|
|
13
19
|
readonly threadId: number;
|
|
14
20
|
private readonly events;
|
|
15
21
|
constructor(spec: ChainSpec, port: MessagePort);
|
|
22
|
+
static fromTransferable(spec: ChainSpec, { port }: TransferablePort): ThreadPort;
|
|
23
|
+
intoTransferable(): TransferablePort;
|
|
16
24
|
close(): void;
|
|
17
25
|
private createListener;
|
|
18
26
|
onClose(callback: (e: Error) => void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/port.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,KAAK,KAAK,EAAoB,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAErE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/port.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,KAAK,KAAK,EAAoB,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAErE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAIF,qDAAqD;AACrD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC;AACF,qBAAa,UAAW,YAAW,IAAI;IAWnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAXvB,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC;IAMtD,SAAgB,QAAQ,SAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG1B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,WAAW;IAcpC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,gBAAgB;IAInE,gBAAgB,IAAI,gBAAgB;IAIpC,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI3C,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IASvF,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IASzF,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;CAWvE"}
|
|
@@ -8,6 +8,10 @@ const logger = Logger.new(import.meta.filename, "workers/api");
|
|
|
8
8
|
export class ThreadPort {
|
|
9
9
|
spec;
|
|
10
10
|
port;
|
|
11
|
+
static pair(spec) {
|
|
12
|
+
const { port1, port2 } = new MessageChannel();
|
|
13
|
+
return [new ThreadPort(spec, port1), new ThreadPort(spec, port2)];
|
|
14
|
+
}
|
|
11
15
|
threadId = threadId;
|
|
12
16
|
events = new EventEmitter();
|
|
13
17
|
constructor(spec, port) {
|
|
@@ -23,6 +27,12 @@ export class ThreadPort {
|
|
|
23
27
|
this.events.emit(eventName, responseId, data);
|
|
24
28
|
});
|
|
25
29
|
}
|
|
30
|
+
static fromTransferable(spec, { port }) {
|
|
31
|
+
return new ThreadPort(spec, port);
|
|
32
|
+
}
|
|
33
|
+
intoTransferable() {
|
|
34
|
+
return { threadId: this.threadId, port: this.port };
|
|
35
|
+
}
|
|
26
36
|
close() {
|
|
27
37
|
this.port.close();
|
|
28
38
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
import { AUTHORSHIP_NETWORK_PORT, protocol as networkProtocol } from "#@typeberry/comms-authorship-network";
|
|
1
2
|
import { Telemetry } from "#@typeberry/telemetry";
|
|
3
|
+
import { Channel } from "#@typeberry/workers-api";
|
|
2
4
|
import { initWorker } from "#@typeberry/workers-api-node";
|
|
3
5
|
import { main } from "./main.js";
|
|
4
|
-
import { BlockAuthorshipConfig, protocol } from "./protocol.js";
|
|
5
|
-
const { config, comms } = await initWorker(
|
|
6
|
+
import { BlockAuthorshipConfig, protocol as mainProtocol } from "./protocol.js";
|
|
7
|
+
const { config, comms } = await initWorker(mainProtocol, BlockAuthorshipConfig.Codec);
|
|
6
8
|
// Initialize OpenTelemetry for this worker
|
|
7
9
|
const tele = Telemetry.initialize({
|
|
8
10
|
worker: "generator",
|
|
9
11
|
nodeName: config.nodeName,
|
|
10
12
|
});
|
|
11
|
-
|
|
13
|
+
const port = config.ports.get(AUTHORSHIP_NETWORK_PORT);
|
|
14
|
+
if (port === undefined) {
|
|
15
|
+
throw new Error("Network port not found in config");
|
|
16
|
+
}
|
|
17
|
+
const networkingComms = Channel.tx(networkProtocol, port);
|
|
18
|
+
await main(config, comms, networkingComms);
|
|
12
19
|
await tele?.close();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { NetworkingComms } from "#@typeberry/comms-authorship-network";
|
|
1
2
|
import type { WorkerConfig } from "#@typeberry/workers-api";
|
|
2
3
|
import type { BlockAuthorshipConfig, GeneratorInternal } from "./protocol.js";
|
|
3
4
|
type Config = WorkerConfig<BlockAuthorshipConfig>;
|
|
4
|
-
export declare function main(config: Config, comms: GeneratorInternal): Promise<void>;
|
|
5
|
+
export declare function main(config: Config, comms: GeneratorInternal, networkingComms: NetworkingComms): Promise<void>;
|
|
5
6
|
export {};
|
|
6
7
|
//# sourceMappingURL=main.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/block-authorship/main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/block-authorship/main.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAgB3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAK9E,KAAK,MAAM,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAkBlD,wBAAsB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,iBAgPpG"}
|
|
@@ -15,7 +15,7 @@ import { asOpaqueType, assertNever, Result } from "#@typeberry/utils";
|
|
|
15
15
|
import { Generator } from "./generator.js";
|
|
16
16
|
import { generateTickets } from "./ticket-generator.js";
|
|
17
17
|
const logger = Logger.new(import.meta.filename, "author");
|
|
18
|
-
export async function main(config, comms) {
|
|
18
|
+
export async function main(config, comms, networkingComms) {
|
|
19
19
|
await initWasm();
|
|
20
20
|
logger.info `🎁 Block Authorship running`;
|
|
21
21
|
const chainSpec = config.chainSpec;
|
|
@@ -41,7 +41,15 @@ export async function main(config, comms) {
|
|
|
41
41
|
ed25519Secret: secrets.ed25519,
|
|
42
42
|
ed25519Public: await deriveEd25519PublicKey(secrets.ed25519),
|
|
43
43
|
})));
|
|
44
|
+
const initialHash = blocks.getBestHeaderHash();
|
|
45
|
+
const initialState = states.getState(initialHash);
|
|
44
46
|
logger.info `Block authorship validator keys: ${keys.map(({ bandersnatchPublic }, index) => `\n ${index}: ${bandersnatchPublic.toString()}`)}`;
|
|
47
|
+
if (initialState !== null) {
|
|
48
|
+
const initialKeys = await getSealingKeySeries(startTimeSlot % chainSpec.epochLength === 0, startTimeSlot, initialState);
|
|
49
|
+
if (initialKeys.isOk) {
|
|
50
|
+
logEpochBlockCreation(tryAsEpoch(Math.floor(startTimeSlot / chainSpec.epochLength)), initialKeys.ok);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
45
53
|
function getTime() {
|
|
46
54
|
const currentTime = process.hrtime.bigint() / 1000000n;
|
|
47
55
|
const timeFromStart = currentTime - startTime;
|
|
@@ -77,6 +85,21 @@ export async function main(config, comms) {
|
|
|
77
85
|
const currentEpoch = Math.floor(currentTimeslot / chainSpec.epochLength);
|
|
78
86
|
return currentEpoch > lastEpoch;
|
|
79
87
|
}
|
|
88
|
+
function logEpochBlockCreation(epoch, sealingKeySeries) {
|
|
89
|
+
let isCreating = false;
|
|
90
|
+
const epochStart = epoch * chainSpec.epochLength;
|
|
91
|
+
const epochEnd = epochStart + chainSpec.epochLength;
|
|
92
|
+
for (let slot = epochStart; slot < epochEnd; slot++) {
|
|
93
|
+
const key = getKeyForCurrentSlot(sealingKeySeries, keys, tryAsTimeSlot(slot));
|
|
94
|
+
if (key !== null) {
|
|
95
|
+
isCreating = true;
|
|
96
|
+
logger.info `[EPOCH ${epoch}] Validator ${key.bandersnatchPublic.toString()} will author block at slot ${slot}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (isCreating === false) {
|
|
100
|
+
logger.info `[EPOCH ${epoch}] No blocks to author for this epoch.`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
80
103
|
async function getSealingKeySeries(isNewEpoch, timeSlot, state) {
|
|
81
104
|
if (isNewEpoch) {
|
|
82
105
|
const safrole = new Safrole(chainSpec, blake2bHasher, state);
|
|
@@ -129,13 +152,14 @@ export async function main(config, comms) {
|
|
|
129
152
|
// After epoch change, it has been shifted to index 2.
|
|
130
153
|
const ticketEntropy = isNewEpoch ? state.entropy[1] : state.entropy[2];
|
|
131
154
|
logger.info `Epoch ${epoch}, slot ${slotInEpoch}/${chainSpec.contestLength}. Generating tickets for ${validatorKeys.length} validators...`;
|
|
132
|
-
const ticketsResult = await generateTickets(bandersnatch, ringKeys, validatorKeys, ticketEntropy, chainSpec.ticketsPerValidator);
|
|
155
|
+
const ticketsResult = await generateTickets(bandersnatch, ringKeys, validatorKeys, ticketEntropy, chainSpec.ticketsPerValidator, chainSpec);
|
|
133
156
|
if (ticketsResult.isError) {
|
|
134
157
|
logger.warn `Failed to generate tickets for epoch ${epoch}: ${ticketsResult.error}`;
|
|
135
158
|
}
|
|
136
159
|
else {
|
|
137
|
-
logger.log `Generated ${ticketsResult.ok.length} tickets for epoch ${epoch}
|
|
138
|
-
//
|
|
160
|
+
logger.log `Generated ${ticketsResult.ok.length} tickets for epoch ${epoch}. Distributing...`;
|
|
161
|
+
// Send directly to network worker (bypasses main thread)
|
|
162
|
+
await networkingComms.sendTickets({ epochIndex: epoch, tickets: ticketsResult.ok });
|
|
139
163
|
}
|
|
140
164
|
}
|
|
141
165
|
ticketsGeneratedForEpoch = epoch;
|
|
@@ -144,6 +168,9 @@ export async function main(config, comms) {
|
|
|
144
168
|
if (selingKeySeriesResult.isError) {
|
|
145
169
|
continue;
|
|
146
170
|
}
|
|
171
|
+
if (isNewEpoch) {
|
|
172
|
+
logEpochBlockCreation(epoch, selingKeySeriesResult.ok);
|
|
173
|
+
}
|
|
147
174
|
const key = getKeyForCurrentSlot(selingKeySeriesResult.ok, keys, timeSlot);
|
|
148
175
|
if (key !== null && currentValidatorData !== undefined) {
|
|
149
176
|
const validatorIndex = getValidatorIndex(key, currentValidatorData);
|
|
@@ -28,7 +28,7 @@ export declare const protocol: import("@typeberry/workers-api").LousyProtocol<{
|
|
|
28
28
|
ticketsMarker: import("@typeberry/codec").Descriptor<import("@typeberry/block").TicketsMarker | null, import("@typeberry/codec").ViewOf<import("@typeberry/block").TicketsMarker, {
|
|
29
29
|
tickets: import("@typeberry/codec").Descriptor<readonly import("@typeberry/block").Ticket[] & import("@typeberry/utils").WithOpaque<"EpochLength">, import("@typeberry/codec").SequenceView<import("@typeberry/block").Ticket, import("@typeberry/codec").ViewOf<import("@typeberry/block").Ticket, {
|
|
30
30
|
id: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<32>, import("@typeberry/bytes").Bytes<32>>;
|
|
31
|
-
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").
|
|
31
|
+
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").U32>;
|
|
32
32
|
}>>>;
|
|
33
33
|
}> | null>;
|
|
34
34
|
bandersnatchBlockAuthorIndex: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<2> & import("@typeberry/utils").WithOpaque<"ValidatorIndex[u16]">, import("@typeberry/bytes").Bytes<2>>;
|
|
@@ -38,7 +38,7 @@ export declare const protocol: import("@typeberry/workers-api").LousyProtocol<{
|
|
|
38
38
|
}>>;
|
|
39
39
|
extrinsic: import("@typeberry/codec").Descriptor<import("@typeberry/block").Extrinsic, import("@typeberry/codec").ViewOf<import("@typeberry/block").Extrinsic, {
|
|
40
40
|
tickets: import("@typeberry/codec").Descriptor<readonly import("@typeberry/block").SignedTicket[] & import("@typeberry/utils").WithOpaque<"Size: [0..chainSpec.maxTicketsPerExtrinsic)">, import("@typeberry/codec").SequenceView<import("@typeberry/block").SignedTicket, import("@typeberry/codec").ViewOf<import("@typeberry/block").SignedTicket, {
|
|
41
|
-
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").
|
|
41
|
+
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").U32>;
|
|
42
42
|
signature: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<784> & import("@typeberry/utils").WithOpaque<"BandersnatchRingSignature">, import("@typeberry/bytes").Bytes<784>>;
|
|
43
43
|
}>>>;
|
|
44
44
|
preimages: import("@typeberry/codec").Descriptor<import("@typeberry/block").Preimage[], import("@typeberry/codec").SequenceView<import("@typeberry/block").Preimage, import("@typeberry/codec").ViewOf<import("@typeberry/block").Preimage, {
|
|
@@ -152,7 +152,7 @@ export declare const protocol: import("@typeberry/workers-api").LousyProtocol<{
|
|
|
152
152
|
ticketsMarker: import("@typeberry/codec").Descriptor<import("@typeberry/block").TicketsMarker | null, import("@typeberry/codec").ViewOf<import("@typeberry/block").TicketsMarker, {
|
|
153
153
|
tickets: import("@typeberry/codec").Descriptor<readonly import("@typeberry/block").Ticket[] & import("@typeberry/utils").WithOpaque<"EpochLength">, import("@typeberry/codec").SequenceView<import("@typeberry/block").Ticket, import("@typeberry/codec").ViewOf<import("@typeberry/block").Ticket, {
|
|
154
154
|
id: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<32>, import("@typeberry/bytes").Bytes<32>>;
|
|
155
|
-
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").
|
|
155
|
+
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").U32>;
|
|
156
156
|
}>>>;
|
|
157
157
|
}> | null>;
|
|
158
158
|
bandersnatchBlockAuthorIndex: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<2> & import("@typeberry/utils").WithOpaque<"ValidatorIndex[u16]">, import("@typeberry/bytes").Bytes<2>>;
|
|
@@ -162,7 +162,7 @@ export declare const protocol: import("@typeberry/workers-api").LousyProtocol<{
|
|
|
162
162
|
}>>;
|
|
163
163
|
extrinsic: import("@typeberry/codec").Descriptor<import("@typeberry/block").Extrinsic, import("@typeberry/codec").ViewOf<import("@typeberry/block").Extrinsic, {
|
|
164
164
|
tickets: import("@typeberry/codec").Descriptor<readonly import("@typeberry/block").SignedTicket[] & import("@typeberry/utils").WithOpaque<"Size: [0..chainSpec.maxTicketsPerExtrinsic)">, import("@typeberry/codec").SequenceView<import("@typeberry/block").SignedTicket, import("@typeberry/codec").ViewOf<import("@typeberry/block").SignedTicket, {
|
|
165
|
-
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").
|
|
165
|
+
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").U32>;
|
|
166
166
|
signature: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<784> & import("@typeberry/utils").WithOpaque<"BandersnatchRingSignature">, import("@typeberry/bytes").Bytes<784>>;
|
|
167
167
|
}>>>;
|
|
168
168
|
preimages: import("@typeberry/codec").Descriptor<import("@typeberry/block").Preimage[], import("@typeberry/codec").SequenceView<import("@typeberry/block").Preimage, import("@typeberry/codec").ViewOf<import("@typeberry/block").Preimage, {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { EntropyHash } from "#@typeberry/block";
|
|
2
|
-
import {
|
|
2
|
+
import type { SignedTicket } from "#@typeberry/block/tickets.js";
|
|
3
|
+
import type { ChainSpec } from "#@typeberry/config";
|
|
3
4
|
import type { BandersnatchKey, BandersnatchSecretSeed } from "#@typeberry/crypto";
|
|
4
5
|
import type { BandernsatchWasm } from "#@typeberry/safrole/bandersnatch-wasm.js";
|
|
5
6
|
import { Result } from "#@typeberry/utils";
|
|
@@ -17,5 +18,5 @@ export type ValidatorKey = {
|
|
|
17
18
|
* Each validator key produces `ticketsPerValidator` tickets using ring VRF proofs.
|
|
18
19
|
* The ring keys define the anonymous set - only members can produce valid proofs.
|
|
19
20
|
*/
|
|
20
|
-
export declare function generateTickets(bandersnatch: BandernsatchWasm, ringKeys: BandersnatchKey[], validatorKeys: ValidatorKey[], entropy: EntropyHash, ticketsPerValidator: number): Promise<Result<SignedTicket[], TicketGeneratorError>>;
|
|
21
|
+
export declare function generateTickets(bandersnatch: BandernsatchWasm, ringKeys: BandersnatchKey[], validatorKeys: ValidatorKey[], entropy: EntropyHash, ticketsPerValidator: number, chainSpec: ChainSpec): Promise<Result<SignedTicket[], TicketGeneratorError>>;
|
|
21
22
|
//# sourceMappingURL=ticket-generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket-generator.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/block-authorship/ticket-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ticket-generator.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/block-authorship/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,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,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;;;;;GAKG;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,EAC3B,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAmCvD"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
|
|
2
1
|
import { Logger } from "#@typeberry/logger";
|
|
3
2
|
import bandersnatchVrf from "#@typeberry/safrole/bandersnatch-vrf.js";
|
|
4
3
|
import { Result } from "#@typeberry/utils";
|
|
@@ -14,7 +13,7 @@ export var TicketGeneratorError;
|
|
|
14
13
|
* Each validator key produces `ticketsPerValidator` tickets using ring VRF proofs.
|
|
15
14
|
* The ring keys define the anonymous set - only members can produce valid proofs.
|
|
16
15
|
*/
|
|
17
|
-
export async function generateTickets(bandersnatch, ringKeys, validatorKeys, entropy, ticketsPerValidator) {
|
|
16
|
+
export async function generateTickets(bandersnatch, ringKeys, validatorKeys, entropy, ticketsPerValidator, chainSpec) {
|
|
18
17
|
const allTickets = [];
|
|
19
18
|
for (const validatorKey of validatorKeys) {
|
|
20
19
|
const proverIndex = ringKeys.findIndex((k) => k.isEqualTo(validatorKey.public));
|
|
@@ -22,7 +21,7 @@ export async function generateTickets(bandersnatch, ringKeys, validatorKeys, ent
|
|
|
22
21
|
logger.warn `Validator public key not found in the ring, skipping ticket generation for this key`;
|
|
23
22
|
continue;
|
|
24
23
|
}
|
|
25
|
-
const ticketResult = await bandersnatchVrf.generateTickets(bandersnatch, ringKeys, proverIndex, validatorKey.secret, entropy,
|
|
24
|
+
const ticketResult = await bandersnatchVrf.generateTickets(bandersnatch, ringKeys, proverIndex, validatorKey.secret, entropy, ticketsPerValidator, chainSpec);
|
|
26
25
|
if (ticketResult.isOk) {
|
|
27
26
|
allTickets.push(...ticketResult.ok);
|
|
28
27
|
}
|
|
@@ -2,6 +2,7 @@ import assert from "node:assert";
|
|
|
2
2
|
import { afterEach, beforeEach, describe, it, mock } from "node:test";
|
|
3
3
|
import { tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
|
|
4
4
|
import { Bytes } from "#@typeberry/bytes";
|
|
5
|
+
import { tinyChainSpec } from "#@typeberry/config";
|
|
5
6
|
import { BANDERSNATCH_KEY_BYTES, initWasm, SEED_SIZE } from "#@typeberry/crypto";
|
|
6
7
|
import { HASH_SIZE } from "#@typeberry/hash";
|
|
7
8
|
import bandersnatchVrf from "#@typeberry/safrole/bandersnatch-vrf.js";
|
|
@@ -25,7 +26,7 @@ describe("Ticket Generator", () => {
|
|
|
25
26
|
const tickets = [];
|
|
26
27
|
for (let attempt = 0; attempt < ticketsPerValidator; attempt++) {
|
|
27
28
|
tickets.push({
|
|
28
|
-
attempt: tryAsTicketAttempt(attempt),
|
|
29
|
+
attempt: tryAsTicketAttempt(attempt, tinyChainSpec),
|
|
29
30
|
signature: Bytes.zero(784).asOpaque(),
|
|
30
31
|
});
|
|
31
32
|
}
|
|
@@ -40,7 +41,7 @@ describe("Ticket Generator", () => {
|
|
|
40
41
|
const ringKeys = createMockRingKeys(3);
|
|
41
42
|
const validatorKeys = createMockValidatorKeys(3);
|
|
42
43
|
const ticketsPerValidator = 2;
|
|
43
|
-
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, validatorKeys, MOCK_ENTROPY, ticketsPerValidator);
|
|
44
|
+
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, validatorKeys, MOCK_ENTROPY, ticketsPerValidator, tinyChainSpec);
|
|
44
45
|
assert.ok(result.isOk);
|
|
45
46
|
assert.strictEqual(result.ok.length, 6);
|
|
46
47
|
});
|
|
@@ -48,18 +49,18 @@ describe("Ticket Generator", () => {
|
|
|
48
49
|
const ringKeys = createMockRingKeys(2);
|
|
49
50
|
const validatorKeys = createMockValidatorKeys(2);
|
|
50
51
|
const ticketsPerValidator = 2;
|
|
51
|
-
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, validatorKeys, MOCK_ENTROPY, ticketsPerValidator);
|
|
52
|
+
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, validatorKeys, MOCK_ENTROPY, ticketsPerValidator, tinyChainSpec);
|
|
52
53
|
assert.ok(result.isOk);
|
|
53
54
|
const tickets = result.ok;
|
|
54
|
-
assert.strictEqual(tickets[0].attempt, tryAsTicketAttempt(0));
|
|
55
|
-
assert.strictEqual(tickets[1].attempt, tryAsTicketAttempt(1));
|
|
56
|
-
assert.strictEqual(tickets[2].attempt, tryAsTicketAttempt(0));
|
|
57
|
-
assert.strictEqual(tickets[3].attempt, tryAsTicketAttempt(1));
|
|
55
|
+
assert.strictEqual(tickets[0].attempt, tryAsTicketAttempt(0, tinyChainSpec));
|
|
56
|
+
assert.strictEqual(tickets[1].attempt, tryAsTicketAttempt(1, tinyChainSpec));
|
|
57
|
+
assert.strictEqual(tickets[2].attempt, tryAsTicketAttempt(0, tinyChainSpec));
|
|
58
|
+
assert.strictEqual(tickets[3].attempt, tryAsTicketAttempt(1, tinyChainSpec));
|
|
58
59
|
});
|
|
59
60
|
it("should return empty array for no validator keys", async () => {
|
|
60
61
|
const ringKeys = createMockRingKeys(3);
|
|
61
62
|
const ticketsPerValidator = 2;
|
|
62
|
-
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, [], MOCK_ENTROPY, ticketsPerValidator);
|
|
63
|
+
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, [], MOCK_ENTROPY, ticketsPerValidator, tinyChainSpec);
|
|
63
64
|
assert.ok(result.isOk);
|
|
64
65
|
assert.strictEqual(result.ok.length, 0);
|
|
65
66
|
});
|
|
@@ -74,7 +75,7 @@ describe("Ticket Generator", () => {
|
|
|
74
75
|
},
|
|
75
76
|
];
|
|
76
77
|
const validatorKeys = [...correctValidatorKeys, ...incorrectValidatorKeys];
|
|
77
|
-
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, validatorKeys, MOCK_ENTROPY, ticketsPerValidator);
|
|
78
|
+
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, validatorKeys, MOCK_ENTROPY, ticketsPerValidator, tinyChainSpec);
|
|
78
79
|
assert.ok(result.isOk);
|
|
79
80
|
// Only the 2 valid validators should produce tickets
|
|
80
81
|
assert.strictEqual(result.ok.length, 4);
|
|
@@ -92,7 +93,7 @@ describe("Ticket Generator", () => {
|
|
|
92
93
|
public: Bytes.fill(BANDERSNATCH_KEY_BYTES, 98).asOpaque(),
|
|
93
94
|
},
|
|
94
95
|
];
|
|
95
|
-
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, invalidValidatorKeys, MOCK_ENTROPY, ticketsPerValidator);
|
|
96
|
+
const result = await generateTickets(MOCK_BANDERSNATCH, ringKeys, invalidValidatorKeys, MOCK_ENTROPY, ticketsPerValidator, tinyChainSpec);
|
|
96
97
|
assert.ok(result.isError);
|
|
97
98
|
assert.strictEqual(result.error, TicketGeneratorError.TicketGenerationFailed);
|
|
98
99
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/comms-authorship-network/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Api, type Internal } from "#@typeberry/workers-api";
|
|
2
|
+
import { TicketsMessage } from "./tickets-message.js";
|
|
3
|
+
/**
|
|
4
|
+
* Port name for authorship-network direct communication.
|
|
5
|
+
* Used when spawning jam-network worker to pass the port for receiving tickets.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AUTHORSHIP_NETWORK_PORT = "authorship-network";
|
|
8
|
+
/**
|
|
9
|
+
* Protocol for direct communication between block-authorship and jam-network workers.
|
|
10
|
+
*
|
|
11
|
+
* This bypasses the main thread for ticket distribution, reducing latency.
|
|
12
|
+
*/
|
|
13
|
+
export declare const protocol: import("@typeberry/workers-api").LousyProtocol<{
|
|
14
|
+
tickets: {
|
|
15
|
+
request: import("@typeberry/codec").Descriptor<TicketsMessage, import("@typeberry/codec").ViewOf<TicketsMessage, {
|
|
16
|
+
epochIndex: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"Epoch">, import("@typeberry/bytes").Bytes<4>>;
|
|
17
|
+
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, {
|
|
18
|
+
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").U32>;
|
|
19
|
+
signature: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<784> & import("@typeberry/utils").WithOpaque<"BandersnatchRingSignature">, import("@typeberry/bytes").Bytes<784>>;
|
|
20
|
+
}>>>;
|
|
21
|
+
}>>;
|
|
22
|
+
response: import("@typeberry/codec").Descriptor<void, void>;
|
|
23
|
+
};
|
|
24
|
+
}, {}>;
|
|
25
|
+
export type NetworkingComms = Api<typeof protocol>;
|
|
26
|
+
export type AuthorshipComms = Internal<typeof protocol>;
|
|
27
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +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,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;MAUnB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC;AACnD,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,QAAQ,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { codec } from "#@typeberry/codec";
|
|
2
|
+
import { createProtocol } from "#@typeberry/workers-api";
|
|
3
|
+
import { TicketsMessage } from "./tickets-message.js";
|
|
4
|
+
/**
|
|
5
|
+
* Port name for authorship-network direct communication.
|
|
6
|
+
* Used when spawning jam-network worker to pass the port for receiving tickets.
|
|
7
|
+
*/
|
|
8
|
+
export const AUTHORSHIP_NETWORK_PORT = "authorship-network";
|
|
9
|
+
/**
|
|
10
|
+
* Protocol for direct communication between block-authorship and jam-network workers.
|
|
11
|
+
*
|
|
12
|
+
* This bypasses the main thread for ticket distribution, reducing latency.
|
|
13
|
+
*/
|
|
14
|
+
export const protocol = createProtocol("authorship-network", {
|
|
15
|
+
// Messages from block-authorship to jam-network
|
|
16
|
+
toWorker: {
|
|
17
|
+
tickets: {
|
|
18
|
+
request: TicketsMessage.Codec,
|
|
19
|
+
response: codec.nothing,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
// Messages from jam-network to block-authorship (none for now)
|
|
23
|
+
fromWorker: {},
|
|
24
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Epoch } from "#@typeberry/block";
|
|
2
|
+
import { SignedTicket } from "#@typeberry/block/tickets.js";
|
|
3
|
+
import { type CodecRecord } from "#@typeberry/codec";
|
|
4
|
+
import { WithDebug } from "#@typeberry/utils";
|
|
5
|
+
export declare class TicketsMessage extends WithDebug {
|
|
6
|
+
readonly epochIndex: Epoch;
|
|
7
|
+
readonly tickets: SignedTicket[];
|
|
8
|
+
static Codec: import("@typeberry/codec").Descriptor<TicketsMessage, import("@typeberry/codec").ViewOf<TicketsMessage, {
|
|
9
|
+
epochIndex: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"Epoch">, import("@typeberry/bytes").Bytes<4>>;
|
|
10
|
+
tickets: import("@typeberry/codec").Descriptor<SignedTicket[], import("@typeberry/codec").SequenceView<SignedTicket, import("@typeberry/codec").ViewOf<SignedTicket, {
|
|
11
|
+
attempt: import("@typeberry/codec").Descriptor<number & import("@typeberry/numbers").WithBytesRepresentation<1> & import("@typeberry/utils").WithOpaque<"TicketAttempt[0|1|2]">, import("@typeberry/numbers").U32>;
|
|
12
|
+
signature: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<784> & import("@typeberry/utils").WithOpaque<"BandersnatchRingSignature">, import("@typeberry/bytes").Bytes<784>>;
|
|
13
|
+
}>>>;
|
|
14
|
+
}>>;
|
|
15
|
+
static create({ epochIndex, tickets }: CodecRecord<TicketsMessage>): TicketsMessage;
|
|
16
|
+
private constructor();
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=tickets-message.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SignedTicket } from "#@typeberry/block/tickets.js";
|
|
2
|
+
import { codec } from "#@typeberry/codec";
|
|
3
|
+
import { WithDebug } from "#@typeberry/utils";
|
|
4
|
+
export class TicketsMessage extends WithDebug {
|
|
5
|
+
epochIndex;
|
|
6
|
+
tickets;
|
|
7
|
+
static Codec = codec.Class(TicketsMessage, {
|
|
8
|
+
epochIndex: codec.u32.asOpaque(),
|
|
9
|
+
tickets: codec.sequenceVarLen(SignedTicket.Codec),
|
|
10
|
+
});
|
|
11
|
+
static create({ epochIndex, tickets }) {
|
|
12
|
+
return new TicketsMessage(epochIndex, tickets);
|
|
13
|
+
}
|
|
14
|
+
constructor(epochIndex, tickets) {
|
|
15
|
+
super();
|
|
16
|
+
this.epochIndex = epochIndex;
|
|
17
|
+
this.tickets = tickets;
|
|
18
|
+
}
|
|
19
|
+
}
|