@typeberry/lib 0.8.3 → 0.8.4-70b1490

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.
Files changed (144) hide show
  1. package/package.json +6 -4
  2. package/packages/configs/index.d.ts +30 -1
  3. package/packages/configs/index.d.ts.map +1 -1
  4. package/packages/configs/index.js +4 -2
  5. package/packages/configs/typeberry-dev-full.json +29 -0
  6. package/packages/core/bytes/bytes.d.ts +1 -0
  7. package/packages/core/bytes/bytes.d.ts.map +1 -1
  8. package/packages/core/bytes/bytes.js +8 -0
  9. package/packages/core/utils/debug.d.ts +16 -4
  10. package/packages/core/utils/debug.d.ts.map +1 -1
  11. package/packages/core/utils/debug.js +39 -17
  12. package/packages/core/utils/debug.test.js +12 -6
  13. package/packages/jam/config-node/node-config.d.ts +2 -1
  14. package/packages/jam/config-node/node-config.d.ts.map +1 -1
  15. package/packages/jam/config-node/node-config.js +8 -3
  16. package/packages/jam/config-node/node-config.test.js +3 -3
  17. package/packages/jam/database/states.d.ts +7 -0
  18. package/packages/jam/database/states.d.ts.map +1 -1
  19. package/packages/jam/database-fjall/hybrid-states.d.ts +45 -0
  20. package/packages/jam/database-fjall/hybrid-states.d.ts.map +1 -0
  21. package/packages/jam/database-fjall/hybrid-states.js +113 -0
  22. package/packages/jam/database-fjall/hybrid-states.test.d.ts +2 -0
  23. package/packages/jam/database-fjall/hybrid-states.test.d.ts.map +1 -0
  24. package/packages/jam/database-fjall/hybrid-states.test.js +83 -0
  25. package/packages/jam/database-fjall/index.d.ts +3 -0
  26. package/packages/jam/database-fjall/index.d.ts.map +1 -0
  27. package/packages/jam/database-fjall/index.js +2 -0
  28. package/packages/jam/database-fjall/root.d.ts +52 -0
  29. package/packages/jam/database-fjall/root.d.ts.map +1 -0
  30. package/packages/jam/database-fjall/root.js +85 -0
  31. package/packages/jam/database-lmdb/hybrid-states.d.ts +3 -1
  32. package/packages/jam/database-lmdb/hybrid-states.d.ts.map +1 -1
  33. package/packages/jam/database-lmdb/hybrid-states.js +5 -2
  34. package/packages/jam/database-lmdb/root.d.ts +14 -1
  35. package/packages/jam/database-lmdb/root.d.ts.map +1 -1
  36. package/packages/jam/database-lmdb/root.js +25 -5
  37. package/packages/jam/database-lmdb/states.d.ts +1 -0
  38. package/packages/jam/database-lmdb/states.d.ts.map +1 -1
  39. package/packages/jam/database-lmdb/states.js +3 -0
  40. package/packages/jam/database-lmdb/states.test.js +4 -4
  41. package/packages/jam/jamnp-s/tasks/ticket-distribution.d.ts +18 -10
  42. package/packages/jam/jamnp-s/tasks/ticket-distribution.d.ts.map +1 -1
  43. package/packages/jam/jamnp-s/tasks/ticket-distribution.js +44 -68
  44. package/packages/jam/jamnp-s/tasks/ticket-distribution.test.js +30 -8
  45. package/packages/jam/node/main-fuzz.d.ts.map +1 -1
  46. package/packages/jam/node/main-fuzz.js +21 -4
  47. package/packages/jam/node/main-importer.d.ts +7 -4
  48. package/packages/jam/node/main-importer.d.ts.map +1 -1
  49. package/packages/jam/node/main-importer.js +10 -4
  50. package/packages/jam/safrole/bandersnatch-vrf.d.ts +24 -4
  51. package/packages/jam/safrole/bandersnatch-vrf.d.ts.map +1 -1
  52. package/packages/jam/safrole/bandersnatch-vrf.js +92 -40
  53. package/packages/jam/safrole/bandersnatch-vrf.test.js +12 -9
  54. package/packages/jam/safrole/bandersnatch-wasm.d.ts +10 -0
  55. package/packages/jam/safrole/bandersnatch-wasm.d.ts.map +1 -1
  56. package/packages/jam/safrole/bandersnatch-wasm.js +12 -0
  57. package/packages/jam/safrole/safrole.js +5 -5
  58. package/packages/jam/safrole/safrole.test.js +13 -13
  59. package/packages/jam/ticket-pool/index.d.ts +4 -0
  60. package/packages/jam/ticket-pool/index.d.ts.map +1 -0
  61. package/packages/jam/ticket-pool/index.js +3 -0
  62. package/packages/jam/ticket-pool/pending-ticket-pool.d.ts +30 -0
  63. package/packages/jam/ticket-pool/pending-ticket-pool.d.ts.map +1 -0
  64. package/packages/jam/ticket-pool/pending-ticket-pool.js +56 -0
  65. package/packages/jam/ticket-pool/pending-ticket-pool.test.d.ts +2 -0
  66. package/packages/jam/ticket-pool/pending-ticket-pool.test.d.ts.map +1 -0
  67. package/packages/jam/ticket-pool/pending-ticket-pool.test.js +67 -0
  68. package/packages/jam/ticket-pool/ticket-validator.d.ts +47 -0
  69. package/packages/jam/ticket-pool/ticket-validator.d.ts.map +1 -0
  70. package/packages/jam/ticket-pool/ticket-validator.js +34 -0
  71. package/packages/jam/ticket-pool/ticket-validator.test.d.ts +2 -0
  72. package/packages/jam/ticket-pool/ticket-validator.test.d.ts.map +1 -0
  73. package/packages/jam/ticket-pool/ticket-validator.test.js +35 -0
  74. package/packages/jam/ticket-pool/verified-ticket-pool.d.ts +26 -0
  75. package/packages/jam/ticket-pool/verified-ticket-pool.d.ts.map +1 -0
  76. package/packages/jam/ticket-pool/verified-ticket-pool.js +41 -0
  77. package/packages/jam/ticket-pool/verified-ticket-pool.test.d.ts +2 -0
  78. package/packages/jam/ticket-pool/verified-ticket-pool.test.d.ts.map +1 -0
  79. package/packages/jam/ticket-pool/verified-ticket-pool.test.js +54 -0
  80. package/packages/jam/transition/chain-stf.d.ts +2 -1
  81. package/packages/jam/transition/chain-stf.d.ts.map +1 -1
  82. package/packages/jam/transition/chain-stf.js +15 -3
  83. package/packages/workers/api-node/config.d.ts +14 -5
  84. package/packages/workers/api-node/config.d.ts.map +1 -1
  85. package/packages/workers/api-node/config.js +29 -20
  86. package/packages/workers/api-node/config.test.js +38 -1
  87. package/packages/workers/block-authorship/{generator.d.ts → block-generator.d.ts} +5 -5
  88. package/packages/workers/block-authorship/block-generator.d.ts.map +1 -0
  89. package/packages/workers/block-authorship/{generator.js → block-generator.js} +3 -3
  90. package/packages/workers/block-authorship/block-generator.test.d.ts +2 -0
  91. package/packages/workers/block-authorship/block-generator.test.d.ts.map +1 -0
  92. package/packages/workers/block-authorship/{generator.test.js → block-generator.test.js} +8 -8
  93. package/packages/workers/block-authorship/epoch-authoring-slots.d.ts +35 -0
  94. package/packages/workers/block-authorship/epoch-authoring-slots.d.ts.map +1 -0
  95. package/packages/workers/block-authorship/epoch-authoring-slots.js +86 -0
  96. package/packages/workers/block-authorship/epoch-tracker.d.ts +29 -0
  97. package/packages/workers/block-authorship/epoch-tracker.d.ts.map +1 -0
  98. package/packages/workers/block-authorship/epoch-tracker.js +80 -0
  99. package/packages/workers/block-authorship/index.d.ts.map +1 -1
  100. package/packages/workers/block-authorship/index.js +1 -1
  101. package/packages/workers/block-authorship/main.d.ts +3 -0
  102. package/packages/workers/block-authorship/main.d.ts.map +1 -1
  103. package/packages/workers/block-authorship/main.js +197 -315
  104. package/packages/workers/block-authorship/ticket-generator/bootstrap-main.d.ts +2 -0
  105. package/packages/workers/block-authorship/ticket-generator/bootstrap-main.d.ts.map +1 -0
  106. package/packages/workers/block-authorship/ticket-generator/bootstrap-main.js +23 -0
  107. package/packages/workers/block-authorship/ticket-generator/index.d.ts +16 -0
  108. package/packages/workers/block-authorship/ticket-generator/index.d.ts.map +1 -0
  109. package/packages/workers/block-authorship/ticket-generator/index.js +62 -0
  110. package/packages/workers/block-authorship/ticket-generator/protocol.d.ts +50 -0
  111. package/packages/workers/block-authorship/ticket-generator/protocol.d.ts.map +1 -0
  112. package/packages/workers/block-authorship/ticket-generator/protocol.js +54 -0
  113. package/packages/workers/block-authorship/{ticket-generator.d.ts → ticket-generator/ticket-generator.d.ts} +4 -0
  114. package/packages/workers/block-authorship/ticket-generator/ticket-generator.d.ts.map +1 -0
  115. package/packages/workers/block-authorship/{ticket-generator.js → ticket-generator/ticket-generator.js} +19 -9
  116. package/packages/workers/block-authorship/ticket-generator/ticket-generator.test.d.ts.map +1 -0
  117. package/packages/workers/block-authorship/{ticket-generator.test.js → ticket-generator/ticket-generator.test.js} +13 -9
  118. package/packages/workers/block-authorship/ticket-generator/worker-pool.d.ts +36 -0
  119. package/packages/workers/block-authorship/ticket-generator/worker-pool.d.ts.map +1 -0
  120. package/packages/workers/block-authorship/ticket-generator/worker-pool.js +111 -0
  121. package/packages/workers/block-authorship/ticket-validator.d.ts +31 -0
  122. package/packages/workers/block-authorship/ticket-validator.d.ts.map +1 -0
  123. package/packages/workers/block-authorship/ticket-validator.js +59 -0
  124. package/packages/workers/comms-authorship-network/protocol.d.ts +14 -4
  125. package/packages/workers/comms-authorship-network/protocol.d.ts.map +1 -1
  126. package/packages/workers/comms-authorship-network/protocol.js +12 -6
  127. package/packages/workers/comms-authorship-network/tickets-message.d.ts +0 -14
  128. package/packages/workers/comms-authorship-network/tickets-message.d.ts.map +1 -1
  129. package/packages/workers/comms-authorship-network/tickets-message.js +0 -17
  130. package/packages/workers/importer/importer.d.ts +5 -3
  131. package/packages/workers/importer/importer.d.ts.map +1 -1
  132. package/packages/workers/importer/importer.js +43 -35
  133. package/packages/workers/importer/stats.d.ts +36 -0
  134. package/packages/workers/importer/stats.d.ts.map +1 -0
  135. package/packages/workers/importer/stats.js +69 -0
  136. package/packages/workers/jam-network/main.d.ts.map +1 -1
  137. package/packages/workers/jam-network/main.js +25 -4
  138. package/packages/workers/block-authorship/generator.d.ts.map +0 -1
  139. package/packages/workers/block-authorship/generator.test.d.ts +0 -2
  140. package/packages/workers/block-authorship/generator.test.d.ts.map +0 -1
  141. package/packages/workers/block-authorship/ticket-generator.d.ts.map +0 -1
  142. package/packages/workers/block-authorship/ticket-generator.test.d.ts.map +0 -1
  143. /package/packages/configs/{typeberry-dev.json → typeberry-dev-tiny.json} +0 -0
  144. /package/packages/workers/block-authorship/{ticket-generator.test.d.ts → ticket-generator/ticket-generator.test.d.ts} +0 -0
@@ -0,0 +1,56 @@
1
+ import { Logger } from "#@typeberry/logger";
2
+ const logger = Logger.new(import.meta.filename, "pending-pool");
3
+ /**
4
+ * An ordered, signature-deduplicated pool of tickets waiting to be redistributed to peers.
5
+ *
6
+ * Used on the networking side. Indices are stable within an epoch so callers can track
7
+ * per-peer "sent" sets by index. The pool is cleared whenever a new epoch is observed,
8
+ * and tickets for older epochs are dropped (can happen when an async validation completes
9
+ * after the epoch already advanced).
10
+ */
11
+ export class PendingTicketPool {
12
+ tickets = [];
13
+ currentEpochValue = null;
14
+ /** Epoch the pool is currently holding tickets for, or `null` if empty. */
15
+ get currentEpoch() {
16
+ return this.currentEpochValue;
17
+ }
18
+ /** Returns the ordered tickets currently in the pool. Caller must not mutate the array. */
19
+ getTickets() {
20
+ return this.tickets;
21
+ }
22
+ /** Returns true if the ticket was added, false if it was a duplicate or dropped (old epoch). */
23
+ addTicket(epochIndex, ticket) {
24
+ if (this.currentEpochValue !== null && epochIndex < this.currentEpochValue) {
25
+ return false;
26
+ }
27
+ if (this.currentEpochValue !== null && epochIndex > this.currentEpochValue) {
28
+ logger.log `Epoch changed from ${this.currentEpochValue} to ${epochIndex}, clearing ${this.tickets.length} old tickets`;
29
+ this.tickets = [];
30
+ }
31
+ this.currentEpochValue = epochIndex;
32
+ const isDuplicate = this.tickets.some((pending) => pending.epochIndex === epochIndex && pending.ticket.signature.isEqualTo(ticket.signature));
33
+ if (isDuplicate) {
34
+ return false;
35
+ }
36
+ this.tickets.push({ epochIndex, ticket });
37
+ logger.info `[addTicket] Added ticket for epoch ${epochIndex}, total: ${this.tickets.length}`;
38
+ return true;
39
+ }
40
+ /**
41
+ * Replace the pool contents for the given epoch with the supplied tickets. Used when the
42
+ * authorship worker pushes an authoritative pool dump on an epoch boundary; any tickets
43
+ * that aren't in the dump are dropped, and dedup runs over the new set.
44
+ */
45
+ replace(epochIndex, tickets) {
46
+ this.tickets = [];
47
+ this.currentEpochValue = epochIndex;
48
+ for (const ticket of tickets) {
49
+ const isDuplicate = this.tickets.some((pending) => pending.ticket.signature.isEqualTo(ticket.signature));
50
+ if (!isDuplicate) {
51
+ this.tickets.push({ epochIndex, ticket });
52
+ }
53
+ }
54
+ logger.log `Pool replaced for epoch ${epochIndex} with ${this.tickets.length} tickets`;
55
+ }
56
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pending-ticket-pool.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-ticket-pool.test.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/pending-ticket-pool.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import assert from "node:assert";
2
+ import { describe, it } from "node:test";
3
+ import { tryAsEpoch } from "#@typeberry/block";
4
+ import { SignedTicket, tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
5
+ import { Bytes } from "#@typeberry/bytes";
6
+ import { BANDERSNATCH_PROOF_BYTES } from "#@typeberry/crypto";
7
+ import { PendingTicketPool } from "./pending-ticket-pool.js";
8
+ const E1 = tryAsEpoch(1);
9
+ const E2 = tryAsEpoch(2);
10
+ function makeTicket(seed, attempt = 0) {
11
+ const sig = Bytes.zero(BANDERSNATCH_PROOF_BYTES);
12
+ sig.raw[0] = seed;
13
+ return SignedTicket.create({
14
+ attempt: tryAsTicketAttempt(attempt),
15
+ signature: sig.asOpaque(),
16
+ });
17
+ }
18
+ describe("PendingTicketPool", () => {
19
+ it("starts empty with no current epoch", () => {
20
+ const pool = new PendingTicketPool();
21
+ assert.strictEqual(pool.currentEpoch, null);
22
+ assert.deepStrictEqual(pool.getTickets(), []);
23
+ });
24
+ it("adds a ticket and tracks the epoch", () => {
25
+ const pool = new PendingTicketPool();
26
+ const t = makeTicket(1);
27
+ assert.strictEqual(pool.addTicket(E1, t), true);
28
+ assert.strictEqual(pool.currentEpoch, E1);
29
+ assert.strictEqual(pool.getTickets().length, 1);
30
+ });
31
+ it("dedups by signature within an epoch", () => {
32
+ const pool = new PendingTicketPool();
33
+ const t = makeTicket(1);
34
+ pool.addTicket(E1, t);
35
+ assert.strictEqual(pool.addTicket(E1, t), false);
36
+ assert.strictEqual(pool.getTickets().length, 1);
37
+ });
38
+ it("clears tickets when a newer epoch arrives", () => {
39
+ const pool = new PendingTicketPool();
40
+ pool.addTicket(E1, makeTicket(1));
41
+ pool.addTicket(E1, makeTicket(2));
42
+ pool.addTicket(E2, makeTicket(3));
43
+ const tickets = pool.getTickets();
44
+ assert.strictEqual(tickets.length, 1);
45
+ assert.strictEqual(tickets[0].epochIndex, E2);
46
+ assert.strictEqual(pool.currentEpoch, E2);
47
+ });
48
+ it("drops late tickets for older epochs", () => {
49
+ const pool = new PendingTicketPool();
50
+ pool.addTicket(E2, makeTicket(1));
51
+ assert.strictEqual(pool.addTicket(E1, makeTicket(2)), false);
52
+ assert.strictEqual(pool.getTickets().length, 1);
53
+ assert.strictEqual(pool.currentEpoch, E2);
54
+ });
55
+ it("replace clears existing tickets and dedups the new set", () => {
56
+ const pool = new PendingTicketPool();
57
+ pool.addTicket(E1, makeTicket(1));
58
+ pool.addTicket(E1, makeTicket(2));
59
+ const dump = [makeTicket(3), makeTicket(4), makeTicket(3)];
60
+ pool.replace(E2, dump);
61
+ const tickets = pool.getTickets();
62
+ assert.strictEqual(tickets.length, 2);
63
+ assert.strictEqual(pool.currentEpoch, E2);
64
+ assert.strictEqual(tickets[0].ticket.signature.raw[0], 3);
65
+ assert.strictEqual(tickets[1].ticket.signature.raw[0], 4);
66
+ });
67
+ });
@@ -0,0 +1,47 @@
1
+ import type { EntropyHash, Epoch } from "#@typeberry/block";
2
+ import type { SignedTicket } from "#@typeberry/block/tickets.js";
3
+ import { Result } from "#@typeberry/utils";
4
+ /**
5
+ * Outcome of a successful validation.
6
+ *
7
+ * `id` is the entropy hash the validator computed for this ticket. It is `null` when the
8
+ * concrete validator doesn't actually verify (e.g. {@link AcceptTicketsValidator}) or when
9
+ * it delegates to another process that doesn't bother to send the id back over the wire.
10
+ */
11
+ export type ValidatedTicket = {
12
+ ticket: SignedTicket;
13
+ id: EntropyHash;
14
+ };
15
+ /** Reasons a ticket may fail validation. */
16
+ export declare enum ValidationError {
17
+ /** Verifier rejected the signature / proof. */
18
+ InvalidProof = "invalid_proof",
19
+ /** Validator could not run (e.g. state unavailable, transient internal failure). */
20
+ ValidatorUnavailable = "validator_unavailable",
21
+ /** Ticket is for an epoch outside the validator's window of interest. */
22
+ WrongEpoch = "wrong_epoch"
23
+ }
24
+ /**
25
+ * Strategy for verifying tickets arriving from peers.
26
+ *
27
+ * The concrete implementation may call into the bandersnatch verifier, defer to another
28
+ * worker via IPC, or short-circuit (Accept/Deny defaults for tests).
29
+ */
30
+ export interface TicketValidator {
31
+ validate(epochIndex: Epoch, tickets: SignedTicket[]): Promise<Result<ValidatedTicket[], ValidationError>>;
32
+ }
33
+ /**
34
+ * Accepts every ticket without inspection. Useful for unit tests where the validator
35
+ * isn't the subject under test. Must never be used in production.
36
+ */
37
+ export declare class AcceptTicketsValidator implements TicketValidator {
38
+ validate(_epochIndex: Epoch, ticket: SignedTicket[]): Promise<Result<ValidatedTicket[], ValidationError>>;
39
+ }
40
+ /**
41
+ * Rejects every ticket. Used as the default for any task that needs an explicit, real
42
+ * validator wired in before it will accept anything from the network.
43
+ */
44
+ export declare class DenyTicketsValidator implements TicketValidator {
45
+ validate(_epochIndex: Epoch, _tickets: SignedTicket[]): Promise<Result<ValidatedTicket[], ValidationError>>;
46
+ }
47
+ //# sourceMappingURL=ticket-validator.d.ts.map
@@ -0,0 +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;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"}
@@ -0,0 +1,34 @@
1
+ import { Bytes } from "#@typeberry/bytes";
2
+ import { HASH_SIZE } from "#@typeberry/hash";
3
+ import { Result } from "#@typeberry/utils";
4
+ /** Reasons a ticket may fail validation. */
5
+ export var ValidationError;
6
+ (function (ValidationError) {
7
+ /** Verifier rejected the signature / proof. */
8
+ ValidationError["InvalidProof"] = "invalid_proof";
9
+ /** Validator could not run (e.g. state unavailable, transient internal failure). */
10
+ ValidationError["ValidatorUnavailable"] = "validator_unavailable";
11
+ /** Ticket is for an epoch outside the validator's window of interest. */
12
+ ValidationError["WrongEpoch"] = "wrong_epoch";
13
+ })(ValidationError || (ValidationError = {}));
14
+ /**
15
+ * Accepts every ticket without inspection. Useful for unit tests where the validator
16
+ * isn't the subject under test. Must never be used in production.
17
+ */
18
+ export class AcceptTicketsValidator {
19
+ async validate(_epochIndex, ticket) {
20
+ return Result.ok(ticket.map((ticket) => ({
21
+ ticket,
22
+ id: Bytes.zero(HASH_SIZE).asOpaque(),
23
+ })));
24
+ }
25
+ }
26
+ /**
27
+ * Rejects every ticket. Used as the default for any task that needs an explicit, real
28
+ * validator wired in before it will accept anything from the network.
29
+ */
30
+ export class DenyTicketsValidator {
31
+ async validate(_epochIndex, _tickets) {
32
+ return Result.error(ValidationError.ValidatorUnavailable, () => "no ticket validator wired");
33
+ }
34
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ticket-validator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-validator.test.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/ticket-validator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import assert from "node:assert";
2
+ import { describe, it } from "node:test";
3
+ import { tryAsEpoch } from "#@typeberry/block";
4
+ import { SignedTicket, tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
5
+ import { Bytes } from "#@typeberry/bytes";
6
+ import { BANDERSNATCH_PROOF_BYTES } from "#@typeberry/crypto";
7
+ import { HASH_SIZE } from "#@typeberry/hash";
8
+ import { AcceptTicketsValidator, DenyTicketsValidator, ValidationError } from "./ticket-validator.js";
9
+ const E1 = tryAsEpoch(1);
10
+ function makeTicket() {
11
+ return SignedTicket.create({
12
+ attempt: tryAsTicketAttempt(0),
13
+ signature: Bytes.zero(BANDERSNATCH_PROOF_BYTES).asOpaque(),
14
+ });
15
+ }
16
+ describe("AcceptTicketsValidator", () => {
17
+ it("returns ok with zero id", async () => {
18
+ const v = new AcceptTicketsValidator();
19
+ const res = await v.validate(E1, [makeTicket()]);
20
+ assert.strictEqual(res.isOk, true);
21
+ if (res.isOk) {
22
+ assert.strictEqual(res.ok[0].id.toString(), Bytes.zero(HASH_SIZE).toString());
23
+ }
24
+ });
25
+ });
26
+ describe("DenyTicketsValidator", () => {
27
+ it("returns ValidatorUnavailable", async () => {
28
+ const v = new DenyTicketsValidator();
29
+ const res = await v.validate(E1, [makeTicket()]);
30
+ assert.strictEqual(res.isError, true);
31
+ if (res.isError) {
32
+ assert.strictEqual(res.error, ValidationError.ValidatorUnavailable);
33
+ }
34
+ });
35
+ });
@@ -0,0 +1,26 @@
1
+ import type { EntropyHash, Epoch } from "#@typeberry/block";
2
+ import type { SignedTicket } from "#@typeberry/block/tickets.js";
3
+ /** A ticket the validator already verified, paired with the entropy hash (ticket id). */
4
+ export type VerifiedTicket = {
5
+ ticket: SignedTicket;
6
+ id: EntropyHash;
7
+ };
8
+ /**
9
+ * In-memory pool of verified tickets for the current epoch, keyed by ticket id.
10
+ *
11
+ * Used on the authorship side. Tickets are stored per epoch and deduplicated by their
12
+ * computed entropy hash (so duplicates arriving via different peers / paths are coalesced
13
+ * cheaply). The pool only ever needs to hold tickets for one epoch at a time; switching
14
+ * to a new epoch clears everything older.
15
+ */
16
+ export declare class VerifiedTicketPool {
17
+ private readonly perEpoch;
18
+ private readonly idSets;
19
+ static new(): VerifiedTicketPool;
20
+ private constructor();
21
+ /** Add pre-verified tickets to the pool, deduping by id. */
22
+ add(epochIndex: Epoch, verifiedTickets: readonly VerifiedTicket[]): void;
23
+ /** Returns the verified tickets for the given epoch, or an empty array if none. */
24
+ getForEpoch(epochIndex: Epoch): readonly VerifiedTicket[];
25
+ }
26
+ //# sourceMappingURL=verified-ticket-pool.d.ts.map
@@ -0,0 +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,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"}
@@ -0,0 +1,41 @@
1
+ import { HashSet } from "#@typeberry/collections/hash-set.js";
2
+ /**
3
+ * In-memory pool of verified tickets for the current epoch, keyed by ticket id.
4
+ *
5
+ * Used on the authorship side. Tickets are stored per epoch and deduplicated by their
6
+ * computed entropy hash (so duplicates arriving via different peers / paths are coalesced
7
+ * cheaply). The pool only ever needs to hold tickets for one epoch at a time; switching
8
+ * to a new epoch clears everything older.
9
+ */
10
+ export class VerifiedTicketPool {
11
+ perEpoch = new Map();
12
+ idSets = new Map();
13
+ static new() {
14
+ return new VerifiedTicketPool();
15
+ }
16
+ constructor() { }
17
+ /** Add pre-verified tickets to the pool, deduping by id. */
18
+ add(epochIndex, verifiedTickets) {
19
+ if (this.perEpoch.size > 0 && !this.perEpoch.has(epochIndex)) {
20
+ this.perEpoch.clear();
21
+ this.idSets.clear();
22
+ }
23
+ const existing = this.perEpoch.get(epochIndex) ?? [];
24
+ let idSet = this.idSets.get(epochIndex) ?? null;
25
+ if (idSet === null) {
26
+ idSet = HashSet.new();
27
+ this.idSets.set(epochIndex, idSet);
28
+ }
29
+ for (const entry of verifiedTickets) {
30
+ if (!idSet.has(entry.id)) {
31
+ existing.push(entry);
32
+ idSet.insert(entry.id);
33
+ }
34
+ }
35
+ this.perEpoch.set(epochIndex, existing);
36
+ }
37
+ /** Returns the verified tickets for the given epoch, or an empty array if none. */
38
+ getForEpoch(epochIndex) {
39
+ return this.perEpoch.get(epochIndex) ?? [];
40
+ }
41
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verified-ticket-pool.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-ticket-pool.test.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/ticket-pool/verified-ticket-pool.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import assert from "node:assert";
2
+ import { describe, it } from "node:test";
3
+ import { tryAsEpoch } from "#@typeberry/block";
4
+ import { SignedTicket, tryAsTicketAttempt } from "#@typeberry/block/tickets.js";
5
+ import { Bytes } from "#@typeberry/bytes";
6
+ import { BANDERSNATCH_PROOF_BYTES } from "#@typeberry/crypto";
7
+ import { HASH_SIZE } from "#@typeberry/hash";
8
+ import { VerifiedTicketPool } from "./verified-ticket-pool.js";
9
+ const E1 = tryAsEpoch(1);
10
+ const E2 = tryAsEpoch(2);
11
+ function makeTicket(seed) {
12
+ const sig = Bytes.zero(BANDERSNATCH_PROOF_BYTES);
13
+ sig.raw[0] = seed;
14
+ return SignedTicket.create({
15
+ attempt: tryAsTicketAttempt(0),
16
+ signature: sig.asOpaque(),
17
+ });
18
+ }
19
+ function makeId(byte) {
20
+ return Bytes.fill(HASH_SIZE, byte).asOpaque();
21
+ }
22
+ describe("VerifiedTicketPool", () => {
23
+ it("starts empty", () => {
24
+ const pool = VerifiedTicketPool.new();
25
+ assert.deepStrictEqual(pool.getForEpoch(E1), []);
26
+ });
27
+ it("adds and retrieves tickets per epoch", () => {
28
+ const pool = VerifiedTicketPool.new();
29
+ pool.add(E1, [{ ticket: makeTicket(1), id: makeId(0xaa) }]);
30
+ assert.strictEqual(pool.getForEpoch(E1).length, 1);
31
+ assert.deepStrictEqual(pool.getForEpoch(E2), []);
32
+ });
33
+ it("dedups by id", () => {
34
+ const pool = VerifiedTicketPool.new();
35
+ const id = makeId(0x01);
36
+ pool.add(E1, [{ ticket: makeTicket(1), id }]);
37
+ pool.add(E1, [{ ticket: makeTicket(2), id }]);
38
+ assert.strictEqual(pool.getForEpoch(E1).length, 1);
39
+ assert.strictEqual(pool.getForEpoch(E1)[0].ticket.signature.raw[0], 1);
40
+ });
41
+ it("clears previous epochs when a new epoch is added", () => {
42
+ const pool = VerifiedTicketPool.new();
43
+ pool.add(E1, [{ ticket: makeTicket(1), id: makeId(1) }]);
44
+ pool.add(E2, [{ ticket: makeTicket(2), id: makeId(2) }]);
45
+ assert.deepStrictEqual(pool.getForEpoch(E1), []);
46
+ assert.strictEqual(pool.getForEpoch(E2).length, 1);
47
+ });
48
+ it("appends across multiple add() calls for the same epoch", () => {
49
+ const pool = VerifiedTicketPool.new();
50
+ pool.add(E1, [{ ticket: makeTicket(1), id: makeId(1) }]);
51
+ pool.add(E1, [{ ticket: makeTicket(2), id: makeId(2) }]);
52
+ assert.strictEqual(pool.getForEpoch(E1).length, 2);
53
+ });
54
+ });
@@ -6,7 +6,7 @@ import type { DisputesErrorCode } from "#@typeberry/disputes/disputes-error-code
6
6
  import type { SafroleErrorCode, SafroleStateUpdate } from "#@typeberry/safrole/safrole.js";
7
7
  import { type SafroleSealError } from "#@typeberry/safrole/safrole-seal.js";
8
8
  import type { State, WithStateView } from "#@typeberry/state";
9
- import { type ErrorResult, Result, type TaggedError } from "#@typeberry/utils";
9
+ import { type ErrorResult, measure, Result, type TaggedError } from "#@typeberry/utils";
10
10
  import { type ACCUMULATION_ERROR, type AccumulateOptions, type AccumulateStateUpdate } from "./accumulate/index.js";
11
11
  import { type AssurancesError, type AssurancesStateUpdate } from "./assurances.js";
12
12
  import { type AuthorizationStateUpdate } from "./authorization.js";
@@ -59,6 +59,7 @@ export declare class OnChain {
59
59
  readonly chainSpec: ChainSpec;
60
60
  readonly state: State & WithStateView;
61
61
  readonly hasher: TransitionHasher;
62
+ readonly measureAccumulate: ReturnType<typeof measure>;
62
63
  /** Wire up a full on-chain STF from its dependencies. */
63
64
  static assemble(args: {
64
65
  chainSpec: ChainSpec;
@@ -1 +1 @@
1
- {"version":3,"file":"chain-stf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/transition/chain-stf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chain-stf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/transition/chain-stf.ts"],"names":[],"mappings":"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"}
@@ -84,6 +84,7 @@ export class OnChain {
84
84
  chainSpec;
85
85
  state;
86
86
  hasher;
87
+ measureAccumulate;
87
88
  /** Wire up a full on-chain STF from its dependencies. */
88
89
  static assemble(args) {
89
90
  return new OnChain(args.chainSpec, args.state, args.hasher, args.options, args.headerChain);
@@ -104,14 +105,25 @@ export class OnChain {
104
105
  this.accumulateOutput = new AccumulateOutput();
105
106
  this.preimages = new Preimages(state, hasher.blake2b);
106
107
  this.authorization = new Authorization(chainSpec, state);
108
+ this.measureAccumulate = measure(`import:accumulate (${PvmBackend[options.pvm]})`);
107
109
  }
108
110
  /** Pre-populate things worth caching for the next epoch. */
109
111
  async prepareForNextEpoch() {
110
112
  if (await this.isReadyForNextEpoch) {
111
113
  return;
112
114
  }
115
+ const timeslot = this.state.timeslot;
116
+ logger.log `#${timeslot} preparing for next epoch`;
113
117
  const ready = this.safrole.prepareValidatorKeysForNextEpoch(this.state.disputesRecords.punishSet);
114
- this.isReadyForNextEpoch = ready.then((_) => true);
118
+ this.isReadyForNextEpoch = ready.then((x) => {
119
+ if (x.isOk) {
120
+ logger.log `#${timeslot} next epoch ready`;
121
+ }
122
+ else {
123
+ logger.log `#${timeslot} ${x.details()}`;
124
+ }
125
+ return true;
126
+ });
115
127
  }
116
128
  async verifySeal(timeSlot, block) {
117
129
  const sealState = this.safrole.getSafroleSealState(timeSlot);
@@ -205,14 +217,14 @@ export class OnChain {
205
217
  }
206
218
  const { preimages, ...preimagesRest } = preimagesResult.ok;
207
219
  assertEmpty(preimagesRest);
208
- const timerAccumulate = measure(`import:accumulate (${PvmBackend[this.accumulate.options.pvm]})`);
220
+ const timerAccumulate = this.measureAccumulate();
209
221
  // accumulate
210
222
  const accumulateResult = await this.accumulate.transition({
211
223
  slot: timeSlot,
212
224
  reports: availableReports,
213
225
  entropy: entropy[0],
214
226
  });
215
- logger.log `${timerAccumulate()}`;
227
+ logger.log `#${timeSlot} ${timerAccumulate}`;
216
228
  if (accumulateResult.isError) {
217
229
  return stfError(StfErrorKind.Accumulate, accumulateResult);
218
230
  }
@@ -71,13 +71,19 @@ export declare class InMemWorkerConfig<T = undefined> implements WorkerConfig<T,
71
71
  readonly: boolean;
72
72
  }): RootDb<BlocksDb, SerializedStatesDb>;
73
73
  }
74
+ /** Persistent values store backing the hybrid config. */
75
+ export type HybridBackend = "lmdb" | "fjall";
74
76
  /**
75
77
  * Hybrid worker config for the fuzz target: in-memory blocks and leaf sets,
76
- * but large values persisted to LMDB.
78
+ * but large values persisted to disk (LMDB or fjall, selected by `backend`).
79
+ *
80
+ * The fjall backend is opt-in so its performance can be compared against LMDB
81
+ * before committing to it. fjall opens its keyspace asynchronously, hence the
82
+ * async `new`.
77
83
  *
78
84
  * Like `InMemWorkerConfig`, the blocks and leaf sets are shared across the
79
85
  * open/close/reopen dance that genesis init performs, so `openDatabase`
80
- * returns the same instances and a no-op close. The LMDB root is opened once
86
+ * returns the same instances and a no-op close. The values store is opened once
81
87
  * here and closed by `HybridSerializedStates.close()` at importer teardown.
82
88
  *
83
89
  * In-process only: it holds shared mutable state (the in-memory leaf
@@ -91,16 +97,19 @@ export declare class HybridWorkerConfig<T = undefined> implements WorkerConfig<T
91
97
  readonly blake2b: Blake2b;
92
98
  readonly dbPath: string;
93
99
  readonly ephemeral: boolean;
94
- static new<T>({ nodeName, chainSpec, workerParams, blake2b, dbPath, ephemeral, }: {
100
+ readonly compression: boolean;
101
+ private readonly states;
102
+ static new<T>({ nodeName, chainSpec, workerParams, blake2b, dbPath, ephemeral, compression, backend, }: {
95
103
  nodeName: string;
96
104
  chainSpec: ChainSpec;
97
105
  workerParams: T;
98
106
  blake2b: Blake2b;
99
107
  dbPath: string;
100
108
  ephemeral?: boolean;
101
- }): HybridWorkerConfig<T>;
109
+ compression?: boolean;
110
+ backend?: HybridBackend;
111
+ }): Promise<HybridWorkerConfig<T>>;
102
112
  private readonly blocks;
103
- private readonly states;
104
113
  private constructor();
105
114
  openDatabase(_options?: {
106
115
  readonly: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,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;AAQ7B,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;aAyC5E,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;aAI9B,SAAS,EAAE,OAAO;IAjDpC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EACZ,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,MAAM,EACN,OAAO,EACP,KAAiB,EACjB,SAAiB,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;QAChC,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB;IAID,6DAA6D;WAChD,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,kBAAkB;IAkBpF,OAAO;IAaP,YAAY,CAAC,OAAO,GAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAuB,GAAG,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IAavG,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;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,WAAW,EAAE,CAE5E;AAED;;;;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;AAED,yDAAyD;AACzD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAkB,CAAC,CAAC,GAAG,SAAS,CAAE,YAAW,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,CAAC;aAgCnF,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,SAAS;aACpB,YAAY,EAAE,CAAC;aACf,OAAO,EAAE,OAAO;aAChB,MAAM,EAAE,MAAM;aACd,SAAS,EAAE,OAAO;aAClB,WAAW,EAAE,OAAO;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;WAtCZ,GAAG,CAAC,CAAC,EAAE,EAClB,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,OAAO,EACP,MAAM,EACN,SAAiB,EACjB,WAAkB,EAClB,OAAgB,GACjB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,YAAY,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,OAAO,CAAC,EAAE,aAAa,CAAC;KACzB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAUlC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC,OAAO;IAaP,YAAY,CAAC,QAAQ,GAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAuB,GAAG,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CASzG"}