@typeberry/lib 0.8.4 → 0.9.0-1c3f157
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 +6 -4
- 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/collections/sorted-array.d.ts +1 -1
- package/packages/core/collections/sorted-array.d.ts.map +1 -1
- package/packages/core/collections/sorted-array.js +4 -2
- package/packages/core/collections/sorted-array.test.js +10 -0
- package/packages/core/collections/sorted-set.d.ts +1 -1
- package/packages/core/collections/sorted-set.d.ts.map +1 -1
- package/packages/core/collections/sorted-set.js +6 -2
- package/packages/core/collections/sorted-set.test.js +24 -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/core/utils/index.d.ts +1 -0
- package/packages/core/utils/index.d.ts.map +1 -1
- package/packages/core/utils/index.js +1 -0
- package/packages/core/utils/shutdown.d.ts +18 -0
- package/packages/core/utils/shutdown.d.ts.map +1 -0
- package/packages/core/utils/shutdown.js +3 -0
- package/packages/core/utils/shutdown.node.d.ts +5 -0
- package/packages/core/utils/shutdown.node.d.ts.map +1 -0
- package/packages/core/utils/shutdown.node.js +76 -0
- package/packages/core/utils/shutdown.test.d.ts +2 -0
- package/packages/core/utils/shutdown.test.d.ts.map +1 -0
- package/packages/core/utils/shutdown.test.js +164 -0
- package/packages/extensions/ipc/server.d.ts.map +1 -1
- package/packages/extensions/ipc/server.js +7 -0
- package/packages/jam/config-node/node-config.d.ts +22 -3
- package/packages/jam/config-node/node-config.d.ts.map +1 -1
- package/packages/jam/config-node/node-config.js +33 -6
- package/packages/jam/config-node/node-config.test.js +11 -4
- package/packages/jam/database/index.d.ts +1 -0
- package/packages/jam/database/index.d.ts.map +1 -1
- package/packages/jam/database/index.js +1 -0
- package/packages/jam/database/leaf-db-update.d.ts +1 -0
- package/packages/jam/database/leaf-db-update.d.ts.map +1 -1
- package/packages/jam/database/leaf-db-update.js +22 -5
- package/packages/jam/database/leaf-db-update.test.d.ts +2 -0
- package/packages/jam/database/leaf-db-update.test.d.ts.map +1 -0
- package/packages/jam/database/leaf-db-update.test.js +81 -0
- package/packages/jam/database/serialized-states-db.d.ts +1 -0
- package/packages/jam/database/serialized-states-db.d.ts.map +1 -1
- package/packages/jam/database/serialized-states-db.js +4 -0
- package/packages/jam/database/states.d.ts +11 -0
- package/packages/jam/database/states.d.ts.map +1 -1
- package/packages/jam/database/states.js +3 -0
- package/packages/jam/database/value-refs.d.ts +117 -0
- package/packages/jam/database/value-refs.d.ts.map +1 -0
- package/packages/jam/database/value-refs.js +206 -0
- package/packages/jam/database/value-refs.test.d.ts +2 -0
- package/packages/jam/database/value-refs.test.d.ts.map +1 -0
- package/packages/jam/database/value-refs.test.js +165 -0
- package/packages/jam/database-fjall/blocks.d.ts +25 -0
- package/packages/jam/database-fjall/blocks.d.ts.map +1 -0
- package/packages/jam/database-fjall/blocks.js +86 -0
- package/packages/jam/database-fjall/blocks.test.d.ts +2 -0
- package/packages/jam/database-fjall/blocks.test.d.ts.map +1 -0
- package/packages/jam/database-fjall/blocks.test.js +62 -0
- package/packages/jam/database-fjall/hybrid-states.d.ts +96 -0
- package/packages/jam/database-fjall/hybrid-states.d.ts.map +1 -0
- package/packages/jam/database-fjall/hybrid-states.js +218 -0
- package/packages/jam/database-fjall/hybrid-states.test.d.ts +2 -0
- package/packages/jam/database-fjall/hybrid-states.test.d.ts.map +1 -0
- package/packages/jam/database-fjall/hybrid-states.test.js +113 -0
- package/packages/jam/database-fjall/index.d.ts +5 -0
- package/packages/jam/database-fjall/index.d.ts.map +1 -0
- package/packages/jam/database-fjall/index.js +4 -0
- package/packages/jam/database-fjall/root.d.ts +64 -0
- package/packages/jam/database-fjall/root.d.ts.map +1 -0
- package/packages/jam/database-fjall/root.js +105 -0
- package/packages/jam/database-fjall/states.d.ts +31 -0
- package/packages/jam/database-fjall/states.d.ts.map +1 -0
- package/packages/jam/database-fjall/states.js +99 -0
- package/packages/jam/database-fjall/states.test.d.ts +2 -0
- package/packages/jam/database-fjall/states.test.d.ts.map +1 -0
- package/packages/jam/database-fjall/states.test.js +150 -0
- package/packages/jam/database-lmdb/hybrid-states.d.ts +12 -0
- package/packages/jam/database-lmdb/hybrid-states.d.ts.map +1 -1
- package/packages/jam/database-lmdb/hybrid-states.js +45 -4
- package/packages/jam/database-lmdb/states.d.ts +1 -0
- package/packages/jam/database-lmdb/states.d.ts.map +1 -1
- package/packages/jam/database-lmdb/states.js +5 -0
- package/packages/jam/jamnp-s/tasks/ticket-distribution.d.ts +18 -10
- package/packages/jam/jamnp-s/tasks/ticket-distribution.d.ts.map +1 -1
- package/packages/jam/jamnp-s/tasks/ticket-distribution.js +44 -68
- package/packages/jam/jamnp-s/tasks/ticket-distribution.test.js +30 -8
- package/packages/jam/node/export.d.ts.map +1 -1
- package/packages/jam/node/export.js +18 -9
- package/packages/jam/node/main-fuzz.d.ts +4 -1
- package/packages/jam/node/main-fuzz.d.ts.map +1 -1
- package/packages/jam/node/main-fuzz.js +142 -55
- package/packages/jam/node/main-importer.d.ts +15 -3
- package/packages/jam/node/main-importer.d.ts.map +1 -1
- package/packages/jam/node/main-importer.js +30 -14
- package/packages/jam/node/main.d.ts.map +1 -1
- package/packages/jam/node/main.js +42 -15
- package/packages/jam/node/workers.d.ts +4 -4
- package/packages/jam/node/workers.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-vrf.d.ts +24 -4
- package/packages/jam/safrole/bandersnatch-vrf.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-vrf.js +63 -26
- package/packages/jam/safrole/bandersnatch-vrf.test.js +12 -9
- 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/safrole/safrole.js +5 -5
- package/packages/jam/safrole/safrole.test.js +13 -13
- package/packages/jam/ticket-pool/index.d.ts +4 -0
- package/packages/jam/ticket-pool/index.d.ts.map +1 -0
- package/packages/jam/ticket-pool/index.js +3 -0
- package/packages/jam/ticket-pool/pending-ticket-pool.d.ts +30 -0
- package/packages/jam/ticket-pool/pending-ticket-pool.d.ts.map +1 -0
- package/packages/jam/ticket-pool/pending-ticket-pool.js +56 -0
- package/packages/jam/ticket-pool/pending-ticket-pool.test.d.ts +2 -0
- package/packages/jam/ticket-pool/pending-ticket-pool.test.d.ts.map +1 -0
- package/packages/jam/ticket-pool/pending-ticket-pool.test.js +67 -0
- package/packages/jam/ticket-pool/ticket-validator.d.ts +47 -0
- package/packages/jam/ticket-pool/ticket-validator.d.ts.map +1 -0
- package/packages/jam/ticket-pool/ticket-validator.js +34 -0
- package/packages/jam/ticket-pool/ticket-validator.test.d.ts +2 -0
- package/packages/jam/ticket-pool/ticket-validator.test.d.ts.map +1 -0
- package/packages/jam/ticket-pool/ticket-validator.test.js +35 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.d.ts +26 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.d.ts.map +1 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.js +41 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.test.d.ts +2 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.test.d.ts.map +1 -0
- package/packages/jam/ticket-pool/verified-ticket-pool.test.js +54 -0
- package/packages/workers/api/config.d.ts +2 -2
- package/packages/workers/api/config.d.ts.map +1 -1
- package/packages/workers/api/config.js +1 -1
- package/packages/workers/api/port.d.ts +5 -1
- package/packages/workers/api/port.d.ts.map +1 -1
- package/packages/workers/api/port.js +56 -13
- package/packages/workers/api/port.test.js +35 -0
- package/packages/workers/api-node/config.d.ts +65 -9
- package/packages/workers/api-node/config.d.ts.map +1 -1
- package/packages/workers/api-node/config.js +151 -26
- package/packages/workers/api-node/config.test.js +88 -2
- package/packages/workers/api-node/port.d.ts +3 -0
- package/packages/workers/api-node/port.d.ts.map +1 -1
- package/packages/workers/api-node/port.js +31 -2
- package/packages/workers/api-node/port.test.js +17 -0
- package/packages/workers/api-node/protocol.d.ts +3 -3
- package/packages/workers/api-node/protocol.d.ts.map +1 -1
- package/packages/workers/api-node/protocol.js +18 -12
- 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 +198 -316
- 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 +31 -0
- package/packages/workers/block-authorship/ticket-validator.d.ts.map +1 -0
- package/packages/workers/block-authorship/ticket-validator.js +59 -0
- package/packages/workers/comms-authorship-network/protocol.d.ts +14 -4
- package/packages/workers/comms-authorship-network/protocol.d.ts.map +1 -1
- package/packages/workers/comms-authorship-network/protocol.js +12 -6
- 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/finality.d.ts +2 -0
- package/packages/workers/importer/finality.d.ts.map +1 -1
- package/packages/workers/importer/finality.js +8 -1
- 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 +6 -5
- package/packages/workers/importer/main.d.ts +1 -1
- package/packages/workers/importer/main.d.ts.map +1 -1
- package/packages/workers/importer/main.js +1 -1
- 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 +26 -5
- 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,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 @@
|
|
|
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 @@
|
|
|
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
|
+
});
|
|
@@ -11,7 +11,7 @@ export interface WorkerConfig<TParams = void, TBlocks = BlocksDb, TStates = Stat
|
|
|
11
11
|
/** Open database. */
|
|
12
12
|
openDatabase(options?: {
|
|
13
13
|
readonly: boolean;
|
|
14
|
-
}): RootDb<TBlocks, TStates
|
|
14
|
+
}): Promise<RootDb<TBlocks, TStates>>;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Worker config with in-thread database.
|
|
@@ -32,6 +32,6 @@ export declare class DirectWorkerConfig<TParams = void, TBlocks = BlocksDb, TSta
|
|
|
32
32
|
private constructor();
|
|
33
33
|
openDatabase(_options?: {
|
|
34
34
|
readonly: boolean;
|
|
35
|
-
}): RootDb<TBlocks, TStates
|
|
35
|
+
}): Promise<RootDb<TBlocks, TStates>>;
|
|
36
36
|
}
|
|
37
37
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEtE,kCAAkC;AAClC,MAAM,WAAW,YAAY,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ;IAClF,iBAAiB;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,qBAAqB;IACrB,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEtE,kCAAkC;AAClC,MAAM,WAAW,YAAY,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ;IAClF,iBAAiB;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,qBAAqB;IACrB,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;CAClF;AAED;;GAEG;AACH,qBAAa,kBAAkB,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ,CACpF,YAAW,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;aAmBhC,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,SAAS;aACpB,YAAY,EAAE,OAAO;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IArB3B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAClB,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,YAAY,EAAE,MAAM,GACrB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,QAAQ,EAAE,CAAC,CAAC;QACZ,QAAQ,EAAE,CAAC,CAAC;QACZ,YAAY,EAAE,CAAC,CAAC;KACjB,GAAG,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAI/B,OAAO;IAQD,YAAY,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;CAOxF"}
|
|
@@ -44,7 +44,8 @@ export interface Port {
|
|
|
44
44
|
* so there is no need for any serialization - we simply pass the data.
|
|
45
45
|
*/
|
|
46
46
|
export declare class DirectPort implements Port {
|
|
47
|
-
private readonly
|
|
47
|
+
private readonly inbound;
|
|
48
|
+
private readonly outbound;
|
|
48
49
|
readonly threadId = 0;
|
|
49
50
|
/** Create a pair of symmetrical inter-connected ports. */
|
|
50
51
|
static pair(): [DirectPort, DirectPort];
|
|
@@ -54,5 +55,8 @@ export declare class DirectPort implements Port {
|
|
|
54
55
|
once<T>(event: string, _codec: Codec<T>, callback: (msg: Envelope<T>) => void): () => void;
|
|
55
56
|
postMessage<T>(event: string, _codec: Codec<T>, msg: Envelope<T>): void;
|
|
56
57
|
close(): void;
|
|
58
|
+
private queuePending;
|
|
59
|
+
private flushPending;
|
|
60
|
+
private closeState;
|
|
57
61
|
}
|
|
58
62
|
//# sourceMappingURL=port.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,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,CAAC;IAExF;;;;OAIG;IACH,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,CAAC;IAE1F,2EAA2E;IAC3E,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAEvE,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,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,CAAC;IAExF;;;;OAIG;IACH,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,CAAC;IAE1F,2EAA2E;IAC3E,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAEvE,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAAC;CACf;AAOD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,IAAI;IAWnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,QAAQ,CAAC,QAAQ,KAAK;IAEtB,0DAA0D;IAC1D,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;IAMvC,OAAO;IAKP,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI3C,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAaxF,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAuB1F,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IAQvE,KAAK;IAKL,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,UAAU;CAKnB"}
|
|
@@ -6,27 +6,31 @@ import { EventEmitter } from "eventemitter3";
|
|
|
6
6
|
* so there is no need for any serialization - we simply pass the data.
|
|
7
7
|
*/
|
|
8
8
|
export class DirectPort {
|
|
9
|
-
|
|
9
|
+
inbound;
|
|
10
|
+
outbound;
|
|
10
11
|
threadId = 0;
|
|
11
12
|
/** Create a pair of symmetrical inter-connected ports. */
|
|
12
13
|
static pair() {
|
|
13
|
-
const
|
|
14
|
-
|
|
14
|
+
const left = createPortState();
|
|
15
|
+
const right = createPortState();
|
|
16
|
+
return [new DirectPort(left, right), new DirectPort(right, left)];
|
|
15
17
|
}
|
|
16
|
-
constructor(
|
|
17
|
-
this.
|
|
18
|
+
constructor(inbound, outbound) {
|
|
19
|
+
this.inbound = inbound;
|
|
20
|
+
this.outbound = outbound;
|
|
18
21
|
}
|
|
19
22
|
onClose(callback) {
|
|
20
|
-
this.events.on("error", callback);
|
|
23
|
+
this.inbound.events.on("error", callback);
|
|
21
24
|
}
|
|
22
25
|
on(event, _codec, callback) {
|
|
23
26
|
const trigger = (args) => {
|
|
24
27
|
// we simply cast the args, since there is no encoding involved.
|
|
25
28
|
callback(args);
|
|
26
29
|
};
|
|
27
|
-
this.events.on(event, trigger);
|
|
30
|
+
this.inbound.events.on(event, trigger);
|
|
31
|
+
this.flushPending(event, trigger);
|
|
28
32
|
return () => {
|
|
29
|
-
this.events.off(event, trigger);
|
|
33
|
+
this.inbound.events.off(event, trigger);
|
|
30
34
|
};
|
|
31
35
|
}
|
|
32
36
|
once(event, _codec, callback) {
|
|
@@ -34,16 +38,55 @@ export class DirectPort {
|
|
|
34
38
|
// we simply cast the args, since there is no encoding involved.
|
|
35
39
|
callback(args);
|
|
36
40
|
};
|
|
37
|
-
this.
|
|
41
|
+
const pending = this.inbound.pendingMessages.get(event);
|
|
42
|
+
const pendingMessage = pending?.shift();
|
|
43
|
+
if (pending?.length === 0) {
|
|
44
|
+
this.inbound.pendingMessages.delete(event);
|
|
45
|
+
}
|
|
46
|
+
if (pendingMessage !== undefined) {
|
|
47
|
+
trigger(pendingMessage);
|
|
48
|
+
return () => { };
|
|
49
|
+
}
|
|
50
|
+
this.inbound.events.once(event, trigger);
|
|
38
51
|
return () => {
|
|
39
|
-
this.events.off(event, trigger);
|
|
52
|
+
this.inbound.events.off(event, trigger);
|
|
40
53
|
};
|
|
41
54
|
}
|
|
42
55
|
postMessage(event, _codec, msg) {
|
|
43
|
-
this.events.
|
|
56
|
+
if (this.outbound.events.listenerCount(event) === 0) {
|
|
57
|
+
this.queuePending(event, msg);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.outbound.events.emit(event, msg);
|
|
44
61
|
}
|
|
45
62
|
close() {
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
63
|
+
this.closeState(this.inbound);
|
|
64
|
+
this.closeState(this.outbound);
|
|
48
65
|
}
|
|
66
|
+
queuePending(event, msg) {
|
|
67
|
+
const pending = this.outbound.pendingMessages.get(event) ?? [];
|
|
68
|
+
pending.push(msg);
|
|
69
|
+
this.outbound.pendingMessages.set(event, pending);
|
|
70
|
+
}
|
|
71
|
+
flushPending(event, trigger) {
|
|
72
|
+
const pending = this.inbound.pendingMessages.get(event);
|
|
73
|
+
if (pending === undefined) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.inbound.pendingMessages.delete(event);
|
|
77
|
+
for (const msg of pending) {
|
|
78
|
+
trigger(msg);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
closeState(state) {
|
|
82
|
+
state.events.emit("error", new Error("closing channel"));
|
|
83
|
+
state.events.removeAllListeners();
|
|
84
|
+
state.pendingMessages.clear();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function createPortState() {
|
|
88
|
+
return {
|
|
89
|
+
events: new EventEmitter(),
|
|
90
|
+
pendingMessages: new Map(),
|
|
91
|
+
};
|
|
49
92
|
}
|
|
@@ -25,4 +25,39 @@ describe("DirectPort", () => {
|
|
|
25
25
|
data: tryAsU32(10),
|
|
26
26
|
});
|
|
27
27
|
});
|
|
28
|
+
it("should deliver messages sent before the listener is attached", () => {
|
|
29
|
+
const [txPort, rxPort] = DirectPort.pair();
|
|
30
|
+
txPort.postMessage("hello", codec.u32, {
|
|
31
|
+
responseId: "10",
|
|
32
|
+
data: tryAsU32(10),
|
|
33
|
+
});
|
|
34
|
+
let receivedMessage = null;
|
|
35
|
+
rxPort.on("hello", codec.u32, (msg) => {
|
|
36
|
+
receivedMessage = msg;
|
|
37
|
+
});
|
|
38
|
+
assert.deepStrictEqual(receivedMessage, {
|
|
39
|
+
responseId: "10",
|
|
40
|
+
data: tryAsU32(10),
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it("should not let the sender consume its own pending message", () => {
|
|
44
|
+
const [txPort, rxPort] = DirectPort.pair();
|
|
45
|
+
txPort.postMessage("hello", codec.u32, {
|
|
46
|
+
responseId: "10",
|
|
47
|
+
data: tryAsU32(10),
|
|
48
|
+
});
|
|
49
|
+
let senderMessage = null;
|
|
50
|
+
txPort.on("hello", codec.u32, (msg) => {
|
|
51
|
+
senderMessage = msg;
|
|
52
|
+
});
|
|
53
|
+
assert.deepStrictEqual(senderMessage, null);
|
|
54
|
+
let receiverMessage = null;
|
|
55
|
+
rxPort.on("hello", codec.u32, (msg) => {
|
|
56
|
+
receiverMessage = msg;
|
|
57
|
+
});
|
|
58
|
+
assert.deepStrictEqual(receiverMessage, {
|
|
59
|
+
responseId: "10",
|
|
60
|
+
data: tryAsU32(10),
|
|
61
|
+
});
|
|
62
|
+
});
|
|
28
63
|
});
|
|
@@ -2,10 +2,20 @@ import type { MessagePort } from "node:worker_threads";
|
|
|
2
2
|
import { type Decode, type Encode } from "#@typeberry/codec";
|
|
3
3
|
import { ChainSpec } from "#@typeberry/config";
|
|
4
4
|
import { type BlocksDb, type RootDb, type SerializedStatesDb } from "#@typeberry/database";
|
|
5
|
+
import { FjallValuesSession } from "#@typeberry/database-fjall";
|
|
5
6
|
import { Blake2b } from "#@typeberry/hash";
|
|
6
7
|
import type { WorkerConfig } from "#@typeberry/workers-api";
|
|
7
8
|
import { ThreadPort, type TransferablePort } from "./port.js";
|
|
8
|
-
|
|
9
|
+
export { FjallValuesSession };
|
|
10
|
+
/** Persistent regular-node backend. */
|
|
11
|
+
export type PersistentBackend = "lmdb" | "fjall";
|
|
12
|
+
/** Transferable worker config for persistent regular-node workers. */
|
|
13
|
+
export type PersistentWorkerConfig<T> = LmdbWorkerConfig<T> | FjallWorkerConfig<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Worker config for node.js, backed by the LMDB database.
|
|
16
|
+
*
|
|
17
|
+
* @deprecated lmdb is retained as an explicit fallback. Use `FjallWorkerConfig` for regular nodes.
|
|
18
|
+
*/
|
|
9
19
|
export declare class LmdbWorkerConfig<T = void> implements WorkerConfig<T, BlocksDb, SerializedStatesDb> {
|
|
10
20
|
readonly nodeName: string;
|
|
11
21
|
readonly chainSpec: ChainSpec;
|
|
@@ -28,18 +38,51 @@ export declare class LmdbWorkerConfig<T = void> implements WorkerConfig<T, Block
|
|
|
28
38
|
private constructor();
|
|
29
39
|
openDatabase(options?: {
|
|
30
40
|
readonly: boolean;
|
|
31
|
-
}): RootDb<BlocksDb, SerializedStatesDb
|
|
41
|
+
}): Promise<RootDb<BlocksDb, SerializedStatesDb>>;
|
|
42
|
+
/** Convert this config into a thread-transferable object. */
|
|
43
|
+
intoTransferable(paramsCodec: Encode<T>): TransferableConfig;
|
|
44
|
+
}
|
|
45
|
+
/** Worker config for node.js, backed by a shared fjall engine. */
|
|
46
|
+
export declare class FjallWorkerConfig<T = void> implements WorkerConfig<T, BlocksDb, SerializedStatesDb> {
|
|
47
|
+
readonly nodeName: string;
|
|
48
|
+
readonly chainSpec: ChainSpec;
|
|
49
|
+
readonly workerParams: T;
|
|
50
|
+
readonly dbPath: string;
|
|
51
|
+
readonly blake2b: Blake2b;
|
|
52
|
+
readonly ports: Map<string, ThreadPort>;
|
|
53
|
+
readonly ephemeral: boolean;
|
|
54
|
+
readonly cacheSizeBytes: number | undefined;
|
|
55
|
+
static new<T>({ nodeName, chainSpec, workerParams, dbPath, blake2b, ports, ephemeral, cacheSizeBytes, }: {
|
|
56
|
+
nodeName: string;
|
|
57
|
+
chainSpec: ChainSpec;
|
|
58
|
+
workerParams: T;
|
|
59
|
+
dbPath: string;
|
|
60
|
+
blake2b: Blake2b;
|
|
61
|
+
ports?: Map<string, ThreadPort>;
|
|
62
|
+
ephemeral?: boolean;
|
|
63
|
+
cacheSizeBytes?: number;
|
|
64
|
+
}): FjallWorkerConfig<T>;
|
|
65
|
+
/** Restore node config from a transferable config object. */
|
|
66
|
+
static fromTransferable<T>(decodeParams: Decode<T>, config: TransferableConfig): Promise<FjallWorkerConfig<T>>;
|
|
67
|
+
private constructor();
|
|
68
|
+
openDatabase(options?: {
|
|
69
|
+
readonly: boolean;
|
|
70
|
+
}): Promise<RootDb<BlocksDb, SerializedStatesDb>>;
|
|
32
71
|
/** Convert this config into a thread-transferable object. */
|
|
33
72
|
intoTransferable(paramsCodec: Encode<T>): TransferableConfig;
|
|
34
73
|
}
|
|
35
74
|
/** Config that's safe to transfer between worker threads. */
|
|
36
75
|
export type TransferableConfig = {
|
|
76
|
+
databaseBackend: PersistentBackend;
|
|
37
77
|
nodeName: string;
|
|
38
78
|
chainSpec: ChainSpec;
|
|
39
79
|
workerParams: Uint8Array;
|
|
40
80
|
dbPath: string;
|
|
41
81
|
workerPorts: [string, TransferablePort][];
|
|
82
|
+
cacheSizeBytes?: number;
|
|
42
83
|
};
|
|
84
|
+
/** Restore a persistent worker config from its transferable form. */
|
|
85
|
+
export declare function persistentConfigFromTransferable<T>(decodeParams: Decode<T>, config: TransferableConfig): Promise<PersistentWorkerConfig<T>>;
|
|
43
86
|
/**
|
|
44
87
|
* Collect the transferable objects (communication ports) embedded in a config.
|
|
45
88
|
*
|
|
@@ -69,15 +112,20 @@ export declare class InMemWorkerConfig<T = undefined> implements WorkerConfig<T,
|
|
|
69
112
|
private constructor();
|
|
70
113
|
openDatabase(_options?: {
|
|
71
114
|
readonly: boolean;
|
|
72
|
-
}): RootDb<BlocksDb, SerializedStatesDb
|
|
115
|
+
}): Promise<RootDb<BlocksDb, SerializedStatesDb>>;
|
|
73
116
|
}
|
|
117
|
+
/** Persistent values store backing the hybrid config. */
|
|
118
|
+
export type HybridBackend = "lmdb" | "fjall";
|
|
74
119
|
/**
|
|
75
120
|
* Hybrid worker config for the fuzz target: in-memory blocks and leaf sets,
|
|
76
|
-
* but large values persisted to
|
|
121
|
+
* but large values persisted to disk. The `backend` picks where the values go
|
|
122
|
+
* (lmdb or fjall).
|
|
123
|
+
*
|
|
124
|
+
* fjall opens its keyspace asynchronously, that is why `new` here is async.
|
|
77
125
|
*
|
|
78
126
|
* Like `InMemWorkerConfig`, the blocks and leaf sets are shared across the
|
|
79
127
|
* open/close/reopen dance that genesis init performs, so `openDatabase`
|
|
80
|
-
* returns the same instances and a no-op close. The
|
|
128
|
+
* returns the same instances and a no-op close. The values store is opened once
|
|
81
129
|
* here and closed by `HybridSerializedStates.close()` at importer teardown.
|
|
82
130
|
*
|
|
83
131
|
* In-process only: it holds shared mutable state (the in-memory leaf
|
|
@@ -92,7 +140,8 @@ export declare class HybridWorkerConfig<T = undefined> implements WorkerConfig<T
|
|
|
92
140
|
readonly dbPath: string;
|
|
93
141
|
readonly ephemeral: boolean;
|
|
94
142
|
readonly compression: boolean;
|
|
95
|
-
|
|
143
|
+
private readonly states;
|
|
144
|
+
static new<T>({ nodeName, chainSpec, workerParams, blake2b, dbPath, ephemeral, compression, backend, sharedFjallSession, }: {
|
|
96
145
|
nodeName: string;
|
|
97
146
|
chainSpec: ChainSpec;
|
|
98
147
|
workerParams: T;
|
|
@@ -100,12 +149,19 @@ export declare class HybridWorkerConfig<T = undefined> implements WorkerConfig<T
|
|
|
100
149
|
dbPath: string;
|
|
101
150
|
ephemeral?: boolean;
|
|
102
151
|
compression?: boolean;
|
|
103
|
-
|
|
152
|
+
backend?: HybridBackend;
|
|
153
|
+
/**
|
|
154
|
+
* Reuse an already-open fjall values session instead of opening a fresh
|
|
155
|
+
* keyspace. The fuzz target opens one per run and passes it on every reset,
|
|
156
|
+
* so only the in-memory blocks/leaf sets are rebuilt per vector. Ignored
|
|
157
|
+
* unless `backend === "fjall"`.
|
|
158
|
+
*/
|
|
159
|
+
sharedFjallSession?: FjallValuesSession;
|
|
160
|
+
}): Promise<HybridWorkerConfig<T>>;
|
|
104
161
|
private readonly blocks;
|
|
105
|
-
private readonly states;
|
|
106
162
|
private constructor();
|
|
107
163
|
openDatabase(_options?: {
|
|
108
164
|
readonly: boolean;
|
|
109
|
-
}): RootDb<BlocksDb, SerializedStatesDb
|
|
165
|
+
}): Promise<RootDb<BlocksDb, SerializedStatesDb>>;
|
|
110
166
|
}
|
|
111
167
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/config.ts"],"names":[],"mappings":"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"}
|