@typeberry/jam 0.0.5-f91bac5 → 0.1.0-08a9db1
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/block-generator/index.js +15 -8
- package/block-generator/index.js.map +1 -1
- package/importer/index.js +119 -481
- package/importer/index.js.map +1 -1
- package/index.js +7374 -648
- package/index.js.map +1 -1
- package/jam-network/index.js +12 -3
- package/jam-network/index.js.map +1 -1
- package/package.json +1 -1
- package/bandersnatch/6b655f8772c01b768329.js +0 -1
- package/bandersnatch/ccf8ada94096a8f232f5.js +0 -1
- package/bandersnatch/e2fdc1b646378dd96eda.js +0 -1
- package/bandersnatch/index.js +0 -3037
- package/bandersnatch/index.js.map +0 -1
- package/bandersnatch/package.json +0 -3
- package/bandersnatch/sourcemap-register.cjs +0 -1
- package/importer/bootstrap-bandersnatch.mjs.map +0 -1
package/importer/index.js
CHANGED
|
@@ -3561,6 +3561,7 @@ var __webpack_exports__ = {};
|
|
|
3561
3561
|
|
|
3562
3562
|
// EXPORTS
|
|
3563
3563
|
__nccwpck_require__.d(__webpack_exports__, {
|
|
3564
|
+
F: () => (/* binding */ createImporter),
|
|
3564
3565
|
i: () => (/* binding */ main)
|
|
3565
3566
|
});
|
|
3566
3567
|
|
|
@@ -4223,10 +4224,17 @@ async function initAll() {
|
|
|
4223
4224
|
await init.ed25519();
|
|
4224
4225
|
await init.reedSolomon();
|
|
4225
4226
|
}
|
|
4227
|
+
function initOnce(doInit) {
|
|
4228
|
+
let ready = null;
|
|
4229
|
+
return async () => {
|
|
4230
|
+
if (ready === null) ready = doInit();
|
|
4231
|
+
return await ready;
|
|
4232
|
+
};
|
|
4233
|
+
}
|
|
4226
4234
|
const init = {
|
|
4227
|
-
bandersnatch: async () => await bandersnatch_default({ module_or_path: await bandersnatch_bg_default() }),
|
|
4228
|
-
ed25519: async () => await ed25519_wasm_default({ module_or_path: await ed25519_wasm_bg_default() }),
|
|
4229
|
-
reedSolomon: async () => await reed_solomon_wasm_default({ module_or_path: await reed_solomon_wasm_bg_default() })
|
|
4235
|
+
bandersnatch: initOnce(async () => await bandersnatch_default({ module_or_path: await bandersnatch_bg_default() })),
|
|
4236
|
+
ed25519: initOnce(async () => await ed25519_wasm_default({ module_or_path: await ed25519_wasm_bg_default() })),
|
|
4237
|
+
reedSolomon: initOnce(async () => await reed_solomon_wasm_default({ module_or_path: await reed_solomon_wasm_bg_default() }))
|
|
4230
4238
|
};
|
|
4231
4239
|
|
|
4232
4240
|
//#endregion
|
|
@@ -5694,6 +5702,7 @@ async function verifyBatch(input) {
|
|
|
5694
5702
|
|
|
5695
5703
|
;// CONCATENATED MODULE: ./packages/core/hash/hash.ts
|
|
5696
5704
|
|
|
5705
|
+
|
|
5697
5706
|
/**
|
|
5698
5707
|
* Size of the output of the hash functions.
|
|
5699
5708
|
*
|
|
@@ -5703,6 +5712,7 @@ async function verifyBatch(input) {
|
|
|
5703
5712
|
const hash_HASH_SIZE = 32;
|
|
5704
5713
|
/** A hash without last byte (useful for trie representation). */
|
|
5705
5714
|
const TRUNCATED_HASH_SIZE = 31;
|
|
5715
|
+
const ZERO_HASH = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
5706
5716
|
/**
|
|
5707
5717
|
* Container for some object with a hash that is related to this object.
|
|
5708
5718
|
*
|
|
@@ -8535,7 +8545,7 @@ const common_tryAsServiceGas = (v) => opaque_asOpaqueType(numbers_tryAsU64(v));
|
|
|
8535
8545
|
/** Attempt to convert a number into `CoreIndex`. */
|
|
8536
8546
|
const common_tryAsCoreIndex = (v) => opaque_asOpaqueType(numbers_tryAsU16(v));
|
|
8537
8547
|
/** Attempt to convert a number into `Epoch`. */
|
|
8538
|
-
const tryAsEpoch = (v) =>
|
|
8548
|
+
const tryAsEpoch = (v) => asOpaqueType(tryAsU32(v));
|
|
8539
8549
|
function tryAsPerValidator(array, spec) {
|
|
8540
8550
|
debug_check(array.length === spec.validatorsCount, `Invalid per-validator array length. Expected ${spec.validatorsCount}, got: ${array.length}`);
|
|
8541
8551
|
return sized_array_asKnownSize(array);
|
|
@@ -15962,14 +15972,12 @@ class WriteablePage extends MemoryPage {
|
|
|
15962
15972
|
|
|
15963
15973
|
|
|
15964
15974
|
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
15975
|
var AccessType;
|
|
15968
15976
|
(function (AccessType) {
|
|
15969
15977
|
AccessType[AccessType["READ"] = 0] = "READ";
|
|
15970
15978
|
AccessType[AccessType["WRITE"] = 1] = "WRITE";
|
|
15971
15979
|
})(AccessType || (AccessType = {}));
|
|
15972
|
-
const
|
|
15980
|
+
// const logger = Logger.new(import.meta.filename, "pvm:mem");
|
|
15973
15981
|
class Memory {
|
|
15974
15982
|
sbrkIndex;
|
|
15975
15983
|
virtualSbrkIndex;
|
|
@@ -16000,7 +16008,7 @@ class Memory {
|
|
|
16000
16008
|
if (bytes.length === 0) {
|
|
16001
16009
|
return result_Result.ok(result_OK);
|
|
16002
16010
|
}
|
|
16003
|
-
|
|
16011
|
+
// logger.insane(`MEM[${address}] <- ${BytesBlob.blobFrom(bytes)}`);
|
|
16004
16012
|
const pagesResult = this.getPages(address, bytes.length, AccessType.WRITE);
|
|
16005
16013
|
if (pagesResult.isError) {
|
|
16006
16014
|
return result_Result.error(pagesResult.error);
|
|
@@ -16067,7 +16075,7 @@ class Memory {
|
|
|
16067
16075
|
currentPosition += bytesToRead;
|
|
16068
16076
|
bytesLeft -= bytesToRead;
|
|
16069
16077
|
}
|
|
16070
|
-
|
|
16078
|
+
// logger.insane(`MEM[${startAddress}] => ${BytesBlob.blobFrom(result)}`);
|
|
16071
16079
|
return result_Result.ok(result_OK);
|
|
16072
16080
|
}
|
|
16073
16081
|
sbrk(length) {
|
|
@@ -18921,88 +18929,6 @@ class PvmExecutor {
|
|
|
18921
18929
|
|
|
18922
18930
|
|
|
18923
18931
|
|
|
18924
|
-
;// CONCATENATED MODULE: ./workers/importer/import-queue.ts
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
|
|
18928
|
-
|
|
18929
|
-
|
|
18930
|
-
class ImportQueue {
|
|
18931
|
-
spec;
|
|
18932
|
-
importer;
|
|
18933
|
-
toImport = SortedArray.fromSortedArray((a, b) => {
|
|
18934
|
-
const diff = a.timeSlot - b.timeSlot;
|
|
18935
|
-
if (diff < 0) {
|
|
18936
|
-
return Ordering.Greater;
|
|
18937
|
-
}
|
|
18938
|
-
if (diff > 0) {
|
|
18939
|
-
return Ordering.Less;
|
|
18940
|
-
}
|
|
18941
|
-
return Ordering.Equal;
|
|
18942
|
-
});
|
|
18943
|
-
queuedBlocks = HashSet.new();
|
|
18944
|
-
lastEpoch = tryAsEpoch(2 ** 32 - 1);
|
|
18945
|
-
constructor(spec, importer) {
|
|
18946
|
-
this.spec = spec;
|
|
18947
|
-
this.importer = importer;
|
|
18948
|
-
}
|
|
18949
|
-
isCurrentEpoch(timeSlot) {
|
|
18950
|
-
const epoch = Math.floor(timeSlot / this.spec.epochLength);
|
|
18951
|
-
return this.lastEpoch === epoch;
|
|
18952
|
-
}
|
|
18953
|
-
startPreverification() {
|
|
18954
|
-
for (const entry of this.toImport) {
|
|
18955
|
-
if (this.isCurrentEpoch(entry.timeSlot)) {
|
|
18956
|
-
entry.seal = this.importer.preverifySeal(entry.timeSlot, entry.block);
|
|
18957
|
-
}
|
|
18958
|
-
}
|
|
18959
|
-
}
|
|
18960
|
-
static getBlockDetails(block) {
|
|
18961
|
-
let encodedHeader;
|
|
18962
|
-
let timeSlot;
|
|
18963
|
-
try {
|
|
18964
|
-
encodedHeader = block.header.encoded();
|
|
18965
|
-
timeSlot = block.header.view().timeSlotIndex.materialize();
|
|
18966
|
-
}
|
|
18967
|
-
catch {
|
|
18968
|
-
return result_Result.error("invalid");
|
|
18969
|
-
}
|
|
18970
|
-
const headerHash = hashBytes(encodedHeader).asOpaque();
|
|
18971
|
-
return result_Result.ok(new WithHash(headerHash, { block, timeSlot }));
|
|
18972
|
-
}
|
|
18973
|
-
push(details) {
|
|
18974
|
-
const headerHash = details.hash;
|
|
18975
|
-
if (this.queuedBlocks.has(headerHash)) {
|
|
18976
|
-
return result_Result.error("already queued");
|
|
18977
|
-
}
|
|
18978
|
-
const { timeSlot, block } = details.data;
|
|
18979
|
-
const entry = {
|
|
18980
|
-
headerHash,
|
|
18981
|
-
timeSlot,
|
|
18982
|
-
block,
|
|
18983
|
-
seal: this.isCurrentEpoch(timeSlot) ? this.importer.preverifySeal(timeSlot, block) : Promise.resolve(null),
|
|
18984
|
-
};
|
|
18985
|
-
this.toImport.insert(entry);
|
|
18986
|
-
this.queuedBlocks.insert(headerHash);
|
|
18987
|
-
return result_Result.ok(result_OK);
|
|
18988
|
-
}
|
|
18989
|
-
shift() {
|
|
18990
|
-
const entry = this.toImport.pop();
|
|
18991
|
-
if (entry !== undefined) {
|
|
18992
|
-
this.queuedBlocks.delete(entry.headerHash);
|
|
18993
|
-
const blockEpoch = Math.floor(entry.timeSlot / this.spec.epochLength);
|
|
18994
|
-
const hasEpochChanged = this.lastEpoch !== blockEpoch;
|
|
18995
|
-
this.lastEpoch = tryAsEpoch(blockEpoch);
|
|
18996
|
-
// currently removed block is changing the epoch, so fire up
|
|
18997
|
-
// preverifcation for the following blocks.
|
|
18998
|
-
if (hasEpochChanged) {
|
|
18999
|
-
this.startPreverification();
|
|
19000
|
-
}
|
|
19001
|
-
}
|
|
19002
|
-
return entry;
|
|
19003
|
-
}
|
|
19004
|
-
}
|
|
19005
|
-
|
|
19006
18932
|
;// CONCATENATED MODULE: ./packages/jam/transition/block-verifier.ts
|
|
19007
18933
|
|
|
19008
18934
|
|
|
@@ -19016,7 +18942,7 @@ var BlockVerifierError;
|
|
|
19016
18942
|
BlockVerifierError[BlockVerifierError["InvalidStateRoot"] = 4] = "InvalidStateRoot";
|
|
19017
18943
|
BlockVerifierError[BlockVerifierError["AlreadyImported"] = 5] = "AlreadyImported";
|
|
19018
18944
|
})(BlockVerifierError || (BlockVerifierError = {}));
|
|
19019
|
-
const
|
|
18945
|
+
const block_verifier_ZERO_HASH = bytes_Bytes.zero(hash_HASH_SIZE).asOpaque();
|
|
19020
18946
|
class BlockVerifier {
|
|
19021
18947
|
hasher;
|
|
19022
18948
|
blocks;
|
|
@@ -19036,7 +18962,7 @@ class BlockVerifier {
|
|
|
19036
18962
|
// https://graypaper.fluffylabs.dev/#/cc517d7/0c9d000c9d00?v=0.6.5
|
|
19037
18963
|
const parentHash = headerView.parentHeaderHash.materialize();
|
|
19038
18964
|
// importing genesis block
|
|
19039
|
-
if (!parentHash.isEqualTo(
|
|
18965
|
+
if (!parentHash.isEqualTo(block_verifier_ZERO_HASH)) {
|
|
19040
18966
|
const parentBlock = this.blocks.getHeader(parentHash);
|
|
19041
18967
|
if (parentBlock === null) {
|
|
19042
18968
|
return result_Result.error(BlockVerifierError.ParentNotFound, `Parent ${parentHash.toString()} not found`);
|
|
@@ -19549,304 +19475,22 @@ async function verifyTickets(bandersnatch, numberOfValidators, epochRoot, ticket
|
|
|
19549
19475
|
}));
|
|
19550
19476
|
}
|
|
19551
19477
|
|
|
19552
|
-
;// CONCATENATED MODULE:
|
|
19553
|
-
const external_node_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:os");
|
|
19554
|
-
var external_node_os_default = /*#__PURE__*/__nccwpck_require__.n(external_node_os_namespaceObject);
|
|
19555
|
-
;// CONCATENATED MODULE: ./packages/core/concurrent/parent.ts
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
// Amount of tasks in the queue that will trigger creation of new worker thread.
|
|
19559
|
-
// NOTE this might need to be configurable in the future.
|
|
19560
|
-
const QUEUE_SIZE_WORKER_THRESHOLD = 5;
|
|
19561
|
-
/** Execution pool manager. */
|
|
19562
|
-
class Executor {
|
|
19563
|
-
workers;
|
|
19564
|
-
maxWorkers;
|
|
19565
|
-
workerPath;
|
|
19566
|
-
/** Initialize a new concurrent executor given a path to the worker. */
|
|
19567
|
-
static async initialize(workerPath, options) {
|
|
19568
|
-
debug_check(options.maxWorkers > 0, "Max workers has to be positive.");
|
|
19569
|
-
debug_check(options.minWorkers <= options.maxWorkers, "Min workers has to be lower or equal to max workers.");
|
|
19570
|
-
const workers = [];
|
|
19571
|
-
for (let i = 0; i < options.minWorkers; i++) {
|
|
19572
|
-
workers.push(await initWorker(workerPath));
|
|
19573
|
-
}
|
|
19574
|
-
return new Executor(workers, options.maxWorkers, workerPath);
|
|
19575
|
-
}
|
|
19576
|
-
// keeps track of the indices of worker threads that are currently free and available to execute tasks
|
|
19577
|
-
freeWorkerIndices = [];
|
|
19578
|
-
taskQueue = [];
|
|
19579
|
-
isDestroyed = false;
|
|
19580
|
-
isWorkerInitializing = false;
|
|
19581
|
-
constructor(workers, maxWorkers, workerPath) {
|
|
19582
|
-
this.workers = workers;
|
|
19583
|
-
this.maxWorkers = maxWorkers;
|
|
19584
|
-
this.workerPath = workerPath;
|
|
19585
|
-
// intial free workers.
|
|
19586
|
-
for (let i = 0; i < workers.length; i++) {
|
|
19587
|
-
this.freeWorkerIndices.push(i);
|
|
19588
|
-
}
|
|
19589
|
-
}
|
|
19590
|
-
/** Attempt to initialize a new worker. */
|
|
19591
|
-
async initNewWorker(onSuccess = () => { }) {
|
|
19592
|
-
if (this.workers.length >= this.maxWorkers) {
|
|
19593
|
-
// biome-ignore lint/suspicious/noConsole: warning
|
|
19594
|
-
console.warn(`Task queue has ${this.taskQueue.length} pending items and we can't init any more workers.`);
|
|
19595
|
-
return;
|
|
19596
|
-
}
|
|
19597
|
-
if (this.isWorkerInitializing) {
|
|
19598
|
-
return;
|
|
19599
|
-
}
|
|
19600
|
-
this.isWorkerInitializing = true;
|
|
19601
|
-
this.workers.push(await initWorker(this.workerPath));
|
|
19602
|
-
this.freeWorkerIndices.push(this.workers.length - 1);
|
|
19603
|
-
this.isWorkerInitializing = false;
|
|
19604
|
-
onSuccess();
|
|
19605
|
-
}
|
|
19606
|
-
/** Terminate all workers and clear the executor. */
|
|
19607
|
-
async destroy() {
|
|
19608
|
-
for (const worker of this.workers) {
|
|
19609
|
-
worker.port.close();
|
|
19610
|
-
await worker.worker.terminate();
|
|
19611
|
-
}
|
|
19612
|
-
this.workers.length = 0;
|
|
19613
|
-
this.isDestroyed = true;
|
|
19614
|
-
}
|
|
19615
|
-
/** Execute a task with given parameters. */
|
|
19616
|
-
async run(params) {
|
|
19617
|
-
return new Promise((resolve, reject) => {
|
|
19618
|
-
if (this.isDestroyed) {
|
|
19619
|
-
reject("pool destroyed");
|
|
19620
|
-
return;
|
|
19621
|
-
}
|
|
19622
|
-
this.taskQueue.push({
|
|
19623
|
-
params,
|
|
19624
|
-
resolve,
|
|
19625
|
-
reject,
|
|
19626
|
-
});
|
|
19627
|
-
this.processEntryFromTaskQueue();
|
|
19628
|
-
});
|
|
19629
|
-
}
|
|
19630
|
-
/** Process single element from the task queue. */
|
|
19631
|
-
processEntryFromTaskQueue() {
|
|
19632
|
-
const freeWorker = this.freeWorkerIndices.pop();
|
|
19633
|
-
// no free workers available currently,
|
|
19634
|
-
// we will retry when one of the tasks completes.
|
|
19635
|
-
if (freeWorker === undefined) {
|
|
19636
|
-
if (this.taskQueue.length > QUEUE_SIZE_WORKER_THRESHOLD) {
|
|
19637
|
-
this.initNewWorker(() => {
|
|
19638
|
-
// process an entry in this newly initialized worker.
|
|
19639
|
-
this.processEntryFromTaskQueue();
|
|
19640
|
-
});
|
|
19641
|
-
}
|
|
19642
|
-
return;
|
|
19643
|
-
}
|
|
19644
|
-
const task = this.taskQueue.pop();
|
|
19645
|
-
// no tasks in the queue
|
|
19646
|
-
if (task === undefined) {
|
|
19647
|
-
this.freeWorkerIndices.push(freeWorker);
|
|
19648
|
-
return;
|
|
19649
|
-
}
|
|
19650
|
-
const worker = this.workers[freeWorker];
|
|
19651
|
-
worker.runTask(task, () => {
|
|
19652
|
-
// mark the worker as available again
|
|
19653
|
-
this.freeWorkerIndices.push(freeWorker);
|
|
19654
|
-
// and continue processing the queue
|
|
19655
|
-
this.processEntryFromTaskQueue();
|
|
19656
|
-
});
|
|
19657
|
-
}
|
|
19658
|
-
}
|
|
19659
|
-
async function initWorker(workerPath) {
|
|
19660
|
-
// create a worker and initialize communication channel
|
|
19661
|
-
const { port1, port2 } = new MessageChannel();
|
|
19662
|
-
const workerThread = new external_node_worker_threads_namespaceObject.Worker(workerPath, {});
|
|
19663
|
-
workerThread.postMessage(port1, [port1]);
|
|
19664
|
-
// // wait for the worker to start
|
|
19665
|
-
await new Promise((resolve, reject) => {
|
|
19666
|
-
workerThread.once("message", resolve);
|
|
19667
|
-
workerThread.once("error", reject);
|
|
19668
|
-
});
|
|
19669
|
-
// make sure the threads don't prevent the program from stopping.
|
|
19670
|
-
workerThread.unref();
|
|
19671
|
-
return new WorkerChannel(workerThread, port2);
|
|
19672
|
-
}
|
|
19673
|
-
class WorkerChannel {
|
|
19674
|
-
worker;
|
|
19675
|
-
port;
|
|
19676
|
-
constructor(worker, port) {
|
|
19677
|
-
this.worker = worker;
|
|
19678
|
-
this.port = port;
|
|
19679
|
-
}
|
|
19680
|
-
runTask(task, onFinish) {
|
|
19681
|
-
const message = {
|
|
19682
|
-
params: task.params,
|
|
19683
|
-
};
|
|
19684
|
-
// when we receive a response, make sure to process it
|
|
19685
|
-
this.port.once("message", (e) => {
|
|
19686
|
-
if (e.isOk) {
|
|
19687
|
-
task.resolve(e.ok);
|
|
19688
|
-
}
|
|
19689
|
-
else {
|
|
19690
|
-
task.reject(new Error(e.error));
|
|
19691
|
-
}
|
|
19692
|
-
onFinish();
|
|
19693
|
-
});
|
|
19694
|
-
// send the task to work on.
|
|
19695
|
-
this.port.postMessage(message, message.params.getTransferList());
|
|
19696
|
-
}
|
|
19697
|
-
}
|
|
19698
|
-
|
|
19699
|
-
;// CONCATENATED MODULE: ./packages/core/concurrent/worker.ts
|
|
19478
|
+
;// CONCATENATED MODULE: ./packages/jam/safrole/bandersnatch-wasm.ts
|
|
19700
19479
|
|
|
19701
|
-
|
|
19702
|
-
/** A in-worker abstraction. */
|
|
19703
|
-
class ConcurrentWorker {
|
|
19704
|
-
runInternal;
|
|
19705
|
-
state;
|
|
19706
|
-
static new(run, state) {
|
|
19707
|
-
return new ConcurrentWorker(run, state);
|
|
19708
|
-
}
|
|
19709
|
-
constructor(runInternal, state) {
|
|
19710
|
-
this.runInternal = runInternal;
|
|
19711
|
-
this.state = state;
|
|
19712
|
-
}
|
|
19713
|
-
listenToParentPort() {
|
|
19714
|
-
if (external_node_worker_threads_namespaceObject.parentPort === null) {
|
|
19715
|
-
throw new Error("This method is meant to be run inside a worker thread!");
|
|
19716
|
-
}
|
|
19717
|
-
external_node_worker_threads_namespaceObject.parentPort.once("close", () => {
|
|
19718
|
-
process.exit(0);
|
|
19719
|
-
});
|
|
19720
|
-
external_node_worker_threads_namespaceObject.parentPort.once("message", (port) => {
|
|
19721
|
-
this.listenTo(port);
|
|
19722
|
-
// send back readiness signal.
|
|
19723
|
-
external_node_worker_threads_namespaceObject.parentPort?.postMessage("ready");
|
|
19724
|
-
});
|
|
19725
|
-
}
|
|
19726
|
-
listenTo(port) {
|
|
19727
|
-
port.once("close", () => {
|
|
19728
|
-
port.removeAllListeners();
|
|
19729
|
-
process.exit(0);
|
|
19730
|
-
});
|
|
19731
|
-
port.on("message", (ev) => {
|
|
19732
|
-
const { params } = ev;
|
|
19733
|
-
this.run(params)
|
|
19734
|
-
.then((result) => {
|
|
19735
|
-
const response = result_Result.ok(result);
|
|
19736
|
-
port.postMessage(response, result.getTransferList());
|
|
19737
|
-
})
|
|
19738
|
-
.catch((e) => {
|
|
19739
|
-
const response = result_Result.error(`${e}`);
|
|
19740
|
-
port.postMessage(response, []);
|
|
19741
|
-
});
|
|
19742
|
-
});
|
|
19743
|
-
}
|
|
19744
|
-
async run(params) {
|
|
19745
|
-
return await this.runInternal(params, this.state);
|
|
19746
|
-
}
|
|
19747
|
-
async destroy() { }
|
|
19748
|
-
}
|
|
19749
|
-
|
|
19750
|
-
;// CONCATENATED MODULE: ./packages/core/concurrent/index.ts
|
|
19751
|
-
|
|
19752
|
-
|
|
19753
|
-
|
|
19754
|
-
;// CONCATENATED MODULE: ./packages/jam/safrole/bandersnatch-wasm/params.ts
|
|
19755
|
-
var Method;
|
|
19756
|
-
(function (Method) {
|
|
19757
|
-
Method[Method["RingCommitment"] = 0] = "RingCommitment";
|
|
19758
|
-
Method[Method["BatchVerifyTickets"] = 1] = "BatchVerifyTickets";
|
|
19759
|
-
Method[Method["VerifySeal"] = 2] = "VerifySeal";
|
|
19760
|
-
})(Method || (Method = {}));
|
|
19761
|
-
class params_Response {
|
|
19762
|
-
data;
|
|
19763
|
-
constructor(data) {
|
|
19764
|
-
this.data = data;
|
|
19765
|
-
}
|
|
19766
|
-
getTransferList() {
|
|
19767
|
-
return [this.data.buffer];
|
|
19768
|
-
}
|
|
19769
|
-
}
|
|
19770
|
-
class Params {
|
|
19771
|
-
params;
|
|
19772
|
-
constructor(params) {
|
|
19773
|
-
this.params = params;
|
|
19774
|
-
}
|
|
19775
|
-
getTransferList() {
|
|
19776
|
-
return [];
|
|
19777
|
-
}
|
|
19778
|
-
}
|
|
19779
|
-
|
|
19780
|
-
;// CONCATENATED MODULE: ./packages/jam/safrole/bandersnatch-wasm/worker.ts
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
|
|
19784
|
-
|
|
19785
|
-
const worker = ConcurrentWorker.new(async (p) => {
|
|
19786
|
-
await initAll();
|
|
19787
|
-
const params = p.params;
|
|
19788
|
-
const method = params.method;
|
|
19789
|
-
if (method === Method.RingCommitment) {
|
|
19790
|
-
return Promise.resolve(new params_Response(bandersnatch_exports.ring_commitment(params.keys)));
|
|
19791
|
-
}
|
|
19792
|
-
if (method === Method.BatchVerifyTickets) {
|
|
19793
|
-
return Promise.resolve(new params_Response(bandersnatch_exports.batch_verify_tickets(params.ringSize, params.commitment, params.ticketsData, params.contextLength)));
|
|
19794
|
-
}
|
|
19795
|
-
if (method === Method.VerifySeal) {
|
|
19796
|
-
return Promise.resolve(new params_Response(bandersnatch_exports.verify_seal(params.authorKey, params.signature, params.payload, params.auxData)));
|
|
19797
|
-
}
|
|
19798
|
-
debug_assertNever(method);
|
|
19799
|
-
}, null);
|
|
19800
|
-
|
|
19801
|
-
;// CONCATENATED MODULE: ./packages/jam/safrole/bandersnatch-wasm/index.ts
|
|
19802
|
-
|
|
19803
|
-
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
const workerFile = __nccwpck_require__.ab + "bootstrap-bandersnatch.mjs";
|
|
19807
19480
|
class BandernsatchWasm {
|
|
19808
|
-
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
destroy() {
|
|
19813
|
-
return this.executor.destroy();
|
|
19814
|
-
}
|
|
19815
|
-
static async new({ synchronous }) {
|
|
19816
|
-
const workers = external_node_os_default().cpus().length;
|
|
19817
|
-
return new BandernsatchWasm(!synchronous
|
|
19818
|
-
? await Executor.initialize(workerFile, {
|
|
19819
|
-
minWorkers: Math.max(1, Math.floor(workers / 2)),
|
|
19820
|
-
maxWorkers: workers,
|
|
19821
|
-
})
|
|
19822
|
-
: worker);
|
|
19481
|
+
constructor() { }
|
|
19482
|
+
static async new() {
|
|
19483
|
+
await initAll();
|
|
19484
|
+
return new BandernsatchWasm();
|
|
19823
19485
|
}
|
|
19824
19486
|
async verifySeal(authorKey, signature, payload, auxData) {
|
|
19825
|
-
|
|
19826
|
-
method: Method.VerifySeal,
|
|
19827
|
-
authorKey,
|
|
19828
|
-
signature,
|
|
19829
|
-
payload,
|
|
19830
|
-
auxData,
|
|
19831
|
-
}));
|
|
19832
|
-
return x.data;
|
|
19487
|
+
return bandersnatch_exports.verify_seal(authorKey, signature, payload, auxData);
|
|
19833
19488
|
}
|
|
19834
19489
|
async getRingCommitment(keys) {
|
|
19835
|
-
|
|
19836
|
-
method: Method.RingCommitment,
|
|
19837
|
-
keys,
|
|
19838
|
-
}));
|
|
19839
|
-
return x.data;
|
|
19490
|
+
return bandersnatch_exports.ring_commitment(keys);
|
|
19840
19491
|
}
|
|
19841
19492
|
async batchVerifyTicket(ringSize, commitment, ticketsData, contextLength) {
|
|
19842
|
-
|
|
19843
|
-
method: Method.BatchVerifyTickets,
|
|
19844
|
-
ringSize,
|
|
19845
|
-
commitment,
|
|
19846
|
-
ticketsData,
|
|
19847
|
-
contextLength,
|
|
19848
|
-
}));
|
|
19849
|
-
return x.data;
|
|
19493
|
+
return bandersnatch_exports.batch_verify_tickets(ringSize, commitment, ticketsData, contextLength);
|
|
19850
19494
|
}
|
|
19851
19495
|
}
|
|
19852
19496
|
|
|
@@ -19889,7 +19533,7 @@ class Safrole {
|
|
|
19889
19533
|
chainSpec;
|
|
19890
19534
|
state;
|
|
19891
19535
|
bandersnatch;
|
|
19892
|
-
constructor(chainSpec, state, bandersnatch = BandernsatchWasm.new(
|
|
19536
|
+
constructor(chainSpec, state, bandersnatch = BandernsatchWasm.new()) {
|
|
19893
19537
|
this.chainSpec = chainSpec;
|
|
19894
19538
|
this.state = state;
|
|
19895
19539
|
this.bandersnatch = bandersnatch;
|
|
@@ -20267,7 +19911,7 @@ var SafroleSealError;
|
|
|
20267
19911
|
const BANDERSNATCH_ZERO_KEY = bytes_Bytes.zero(BANDERSNATCH_KEY_BYTES).asOpaque();
|
|
20268
19912
|
class SafroleSeal {
|
|
20269
19913
|
bandersnatch;
|
|
20270
|
-
constructor(bandersnatch = BandernsatchWasm.new(
|
|
19914
|
+
constructor(bandersnatch = BandernsatchWasm.new()) {
|
|
20271
19915
|
this.bandersnatch = bandersnatch;
|
|
20272
19916
|
}
|
|
20273
19917
|
/**
|
|
@@ -24437,7 +24081,8 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
24437
24081
|
*
|
|
24438
24082
|
* https://graypaper.fluffylabs.dev/#/5f542d7/155c01155f01
|
|
24439
24083
|
*/
|
|
24440
|
-
const isInChain = recentBlocks.has(context.lookupAnchor) ||
|
|
24084
|
+
const isInChain = recentBlocks.has(context.lookupAnchor) ||
|
|
24085
|
+
headerChain.isAncestor(context.lookupAnchorSlot, context.lookupAnchor, context.anchor);
|
|
24441
24086
|
if (!isInChain) {
|
|
24442
24087
|
if (process.env.SKIP_LOOKUP_ANCHOR_CHECK !== undefined) {
|
|
24443
24088
|
verify_contextual_logger.warn(`Lookup anchor check for ${context.lookupAnchor} would fail, but override is active.`);
|
|
@@ -25145,11 +24790,25 @@ class DbHeaderChain {
|
|
|
25145
24790
|
constructor(blocks) {
|
|
25146
24791
|
this.blocks = blocks;
|
|
25147
24792
|
}
|
|
25148
|
-
isAncestor(
|
|
25149
|
-
|
|
25150
|
-
|
|
25151
|
-
|
|
25152
|
-
|
|
24793
|
+
isAncestor(pastHeaderSlot, pastHeader, currentHeader) {
|
|
24794
|
+
let currentHash = currentHeader;
|
|
24795
|
+
for (;;) {
|
|
24796
|
+
// success = we found the right header in the DB
|
|
24797
|
+
if (currentHash.isEqualTo(pastHeader)) {
|
|
24798
|
+
return true;
|
|
24799
|
+
}
|
|
24800
|
+
const current = this.blocks.getHeader(currentHash);
|
|
24801
|
+
// fail if we don't find a parent (unlikely?)
|
|
24802
|
+
if (current === null) {
|
|
24803
|
+
return false;
|
|
24804
|
+
}
|
|
24805
|
+
// fail if we went pass that time slot index
|
|
24806
|
+
if (current.timeSlotIndex.materialize() < pastHeaderSlot) {
|
|
24807
|
+
return false;
|
|
24808
|
+
}
|
|
24809
|
+
// move one block up
|
|
24810
|
+
currentHash = current.parentHeaderHash.materialize();
|
|
24811
|
+
}
|
|
25153
24812
|
}
|
|
25154
24813
|
}
|
|
25155
24814
|
const OFFENDERS_ERROR = "offenders not matching header";
|
|
@@ -25195,11 +24854,11 @@ class OnChain {
|
|
|
25195
24854
|
authorization;
|
|
25196
24855
|
// chapter 13: https://graypaper.fluffylabs.dev/#/68eaa1f/18b60118b601?v=0.6.4
|
|
25197
24856
|
statistics;
|
|
25198
|
-
constructor(chainSpec, state, blocks, hasher
|
|
24857
|
+
constructor(chainSpec, state, blocks, hasher) {
|
|
25199
24858
|
this.chainSpec = chainSpec;
|
|
25200
24859
|
this.state = state;
|
|
25201
24860
|
this.hasher = hasher;
|
|
25202
|
-
const bandersnatch = BandernsatchWasm.new(
|
|
24861
|
+
const bandersnatch = BandernsatchWasm.new();
|
|
25203
24862
|
this.statistics = new Statistics(chainSpec, state);
|
|
25204
24863
|
this.safrole = new Safrole(chainSpec, state, bandersnatch);
|
|
25205
24864
|
this.safroleSeal = new SafroleSeal(bandersnatch);
|
|
@@ -25217,16 +24876,16 @@ class OnChain {
|
|
|
25217
24876
|
const sealState = this.safrole.getSafroleSealState(timeSlot);
|
|
25218
24877
|
return await this.safroleSeal.verifyHeaderSeal(block.header.view(), sealState);
|
|
25219
24878
|
}
|
|
25220
|
-
async transition(block, headerHash,
|
|
24879
|
+
async transition(block, headerHash, omitSealVerification = false) {
|
|
25221
24880
|
const headerView = block.header.view();
|
|
25222
24881
|
const header = block.header.materialize();
|
|
25223
24882
|
const timeSlot = header.timeSlotIndex;
|
|
25224
24883
|
// safrole seal
|
|
25225
|
-
let newEntropyHash
|
|
24884
|
+
let newEntropyHash;
|
|
25226
24885
|
if (omitSealVerification) {
|
|
25227
24886
|
newEntropyHash = hashBytes(header.seal).asOpaque();
|
|
25228
24887
|
}
|
|
25229
|
-
|
|
24888
|
+
else {
|
|
25230
24889
|
const sealResult = await this.verifySeal(timeSlot, block);
|
|
25231
24890
|
if (sealResult.isError) {
|
|
25232
24891
|
return stfError(StfErrorKind.SafroleSeal, sealResult);
|
|
@@ -25333,7 +24992,7 @@ class OnChain {
|
|
|
25333
24992
|
assertEmpty(deferredTransfersRest);
|
|
25334
24993
|
const accumulateRoot = await this.accumulateOutput.transition({ accumulationOutputLog });
|
|
25335
24994
|
// recent history
|
|
25336
|
-
const recentHistoryUpdate =
|
|
24995
|
+
const recentHistoryUpdate = this.recentHistory.transition({
|
|
25337
24996
|
partial: recentHistoryPartialUpdate,
|
|
25338
24997
|
headerHash,
|
|
25339
24998
|
accumulateRoot,
|
|
@@ -25413,6 +25072,7 @@ function checkOffendersMatch(offendersMark, headerOffendersMark) {
|
|
|
25413
25072
|
|
|
25414
25073
|
|
|
25415
25074
|
|
|
25075
|
+
|
|
25416
25076
|
var ImporterErrorKind;
|
|
25417
25077
|
(function (ImporterErrorKind) {
|
|
25418
25078
|
ImporterErrorKind[ImporterErrorKind["Verifier"] = 0] = "Verifier";
|
|
@@ -25440,29 +25100,28 @@ class Importer {
|
|
|
25440
25100
|
throw new Error(`Unable to load best state from header hash: ${currentBestHeaderHash}.`);
|
|
25441
25101
|
}
|
|
25442
25102
|
this.verifier = new BlockVerifier(hasher, blocks);
|
|
25443
|
-
this.stf = new OnChain(spec, state, blocks, hasher
|
|
25103
|
+
this.stf = new OnChain(spec, state, blocks, hasher);
|
|
25444
25104
|
this.state = state;
|
|
25445
25105
|
this.currentHash = currentBestHeaderHash;
|
|
25446
25106
|
logger.info(`😎 Best time slot: ${state.timeslot} (header hash: ${currentBestHeaderHash})`);
|
|
25447
25107
|
}
|
|
25448
|
-
|
|
25449
|
-
|
|
25450
|
-
|
|
25451
|
-
|
|
25452
|
-
|
|
25453
|
-
|
|
25454
|
-
}
|
|
25455
|
-
this.logger.
|
|
25456
|
-
return
|
|
25457
|
-
}
|
|
25458
|
-
|
|
25459
|
-
|
|
25460
|
-
|
|
25461
|
-
|
|
25462
|
-
|
|
25463
|
-
async importBlock(block, preverifiedSeal, omitSealVerification = false) {
|
|
25108
|
+
async importBlock(block, omitSealVerification) {
|
|
25109
|
+
const timer = measure("importBlock");
|
|
25110
|
+
const timeSlot = extractTimeSlot(block);
|
|
25111
|
+
const maybeBestHeader = await this.importBlockInternal(block, omitSealVerification);
|
|
25112
|
+
if (maybeBestHeader.isOk) {
|
|
25113
|
+
const bestHeader = maybeBestHeader.ok;
|
|
25114
|
+
this.logger.info(`🧊 Best block: #${timeSlot} (${bestHeader.hash})`);
|
|
25115
|
+
this.logger.log(timer());
|
|
25116
|
+
return maybeBestHeader;
|
|
25117
|
+
}
|
|
25118
|
+
this.logger.log(`❌ Rejected block #${timeSlot}: ${resultToString(maybeBestHeader)}`);
|
|
25119
|
+
this.logger.log(timer());
|
|
25120
|
+
return maybeBestHeader;
|
|
25121
|
+
}
|
|
25122
|
+
async importBlockInternal(block, omitSealVerification = false) {
|
|
25464
25123
|
const logger = this.logger;
|
|
25465
|
-
logger.log(
|
|
25124
|
+
logger.log("🧱 Attempting to import a new block");
|
|
25466
25125
|
const timerVerify = measure("import:verify");
|
|
25467
25126
|
const hash = await this.verifier.verifyBlock(block);
|
|
25468
25127
|
logger.log(timerVerify());
|
|
@@ -25487,7 +25146,7 @@ class Importer {
|
|
|
25487
25146
|
const headerHash = hash.ok;
|
|
25488
25147
|
logger.log(`🧱 Verified block: Got hash ${headerHash} for block at slot ${timeSlot}.`);
|
|
25489
25148
|
const timerStf = measure("import:stf");
|
|
25490
|
-
const res = await this.stf.transition(block, headerHash,
|
|
25149
|
+
const res = await this.stf.transition(block, headerHash, omitSealVerification);
|
|
25491
25150
|
logger.log(timerStf());
|
|
25492
25151
|
if (res.isError) {
|
|
25493
25152
|
return importerError(ImporterErrorKind.Stf, res);
|
|
@@ -25537,6 +25196,19 @@ class Importer {
|
|
|
25537
25196
|
return stateEntries ?? null;
|
|
25538
25197
|
}
|
|
25539
25198
|
}
|
|
25199
|
+
/**
|
|
25200
|
+
* Attempt to safely extract timeslot of a block.
|
|
25201
|
+
*
|
|
25202
|
+
* NOTE: it may fail if encoding is invalid.
|
|
25203
|
+
*/
|
|
25204
|
+
function extractTimeSlot(block) {
|
|
25205
|
+
try {
|
|
25206
|
+
return block.header.view().timeSlotIndex.materialize();
|
|
25207
|
+
}
|
|
25208
|
+
catch {
|
|
25209
|
+
return tryAsTimeSlot(2 ** 32 - 1);
|
|
25210
|
+
}
|
|
25211
|
+
}
|
|
25540
25212
|
|
|
25541
25213
|
;// CONCATENATED MODULE: ./workers/generic/finished.ts
|
|
25542
25214
|
|
|
@@ -25636,7 +25308,7 @@ function importerStateMachine() {
|
|
|
25636
25308
|
return new machine_StateMachine("importer", initialized, [initialized, ready, finished]);
|
|
25637
25309
|
}
|
|
25638
25310
|
const state_machine_logger = Logger.new(import.meta.filename, "importer");
|
|
25639
|
-
const
|
|
25311
|
+
const importBlockResultCodec = descriptors_codec.custom({
|
|
25640
25312
|
name: "Result<StateRootHash, string>",
|
|
25641
25313
|
sizeHint: { bytes: 1, isExact: false },
|
|
25642
25314
|
}, (e, x) => {
|
|
@@ -25704,7 +25376,7 @@ class MainReady extends State {
|
|
|
25704
25376
|
async importBlock(port, block) {
|
|
25705
25377
|
const res = await port.sendRequest("importBlock", block, [block.buffer]);
|
|
25706
25378
|
if (res instanceof Uint8Array) {
|
|
25707
|
-
return decoder_Decoder.decodeObject(
|
|
25379
|
+
return decoder_Decoder.decodeObject(importBlockResultCodec, res);
|
|
25708
25380
|
}
|
|
25709
25381
|
return result_Result.error("Invalid worker response.");
|
|
25710
25382
|
}
|
|
@@ -25752,6 +25424,9 @@ class ImporterReady extends State {
|
|
|
25752
25424
|
this.importer = importer;
|
|
25753
25425
|
this.onImporter.emit();
|
|
25754
25426
|
}
|
|
25427
|
+
setConfig(config) {
|
|
25428
|
+
this.data = config;
|
|
25429
|
+
}
|
|
25755
25430
|
getConfig() {
|
|
25756
25431
|
if (this.data === null) {
|
|
25757
25432
|
throw new Error("Did not receive chain spec config!");
|
|
@@ -25797,7 +25472,6 @@ class ImporterReady extends State {
|
|
|
25797
25472
|
response: rootHash === null ? bytes_Bytes.zero(hash_HASH_SIZE).raw : rootHash.raw,
|
|
25798
25473
|
};
|
|
25799
25474
|
}
|
|
25800
|
-
// NOTE [ToDr] This should rather be using the import queue, instead of going directly.
|
|
25801
25475
|
async importBlock(block) {
|
|
25802
25476
|
if (this.importer === null) {
|
|
25803
25477
|
state_machine_logger.error(`${this.constructor.name} importer not initialized yet!`);
|
|
@@ -25809,17 +25483,13 @@ class ImporterReady extends State {
|
|
|
25809
25483
|
if (block instanceof Uint8Array) {
|
|
25810
25484
|
const config = this.getConfig();
|
|
25811
25485
|
const blockView = decoder_Decoder.decodeObject(Block.Codec.View, block, config.chainSpec);
|
|
25812
|
-
const headerView = blockView.header.view();
|
|
25813
|
-
const timeSlot = headerView.timeSlotIndex.materialize();
|
|
25814
25486
|
let response;
|
|
25815
25487
|
try {
|
|
25816
|
-
const res = await this.importer.importBlock(blockView,
|
|
25488
|
+
const res = await this.importer.importBlock(blockView, config.omitSealVerification);
|
|
25817
25489
|
if (res.isOk) {
|
|
25818
|
-
|
|
25819
|
-
response = result_Result.ok(this.importer.getBestStateRootHash() ?? bytes_Bytes.zero(hash_HASH_SIZE).asOpaque());
|
|
25490
|
+
response = result_Result.ok(this.importer.getBestStateRootHash() ?? ZERO_HASH.asOpaque());
|
|
25820
25491
|
}
|
|
25821
25492
|
else {
|
|
25822
|
-
state_machine_logger.log(`❌ Rejected block #${timeSlot}: ${resultToString(res)}`);
|
|
25823
25493
|
response = result_Result.error(resultToString(res));
|
|
25824
25494
|
}
|
|
25825
25495
|
}
|
|
@@ -25828,7 +25498,7 @@ class ImporterReady extends State {
|
|
|
25828
25498
|
state_machine_logger.error(`${e instanceof Error ? e.stack : ""}`);
|
|
25829
25499
|
response = result_Result.error(`${e}`);
|
|
25830
25500
|
}
|
|
25831
|
-
const encoded = encoder_Encoder.encodeObject(
|
|
25501
|
+
const encoded = encoder_Encoder.encodeObject(importBlockResultCodec, response);
|
|
25832
25502
|
return {
|
|
25833
25503
|
response: encoded.raw,
|
|
25834
25504
|
};
|
|
@@ -25867,8 +25537,6 @@ class ImporterReady extends State {
|
|
|
25867
25537
|
|
|
25868
25538
|
|
|
25869
25539
|
|
|
25870
|
-
|
|
25871
|
-
|
|
25872
25540
|
const importer_logger = Logger.new(import.meta.filename, "importer");
|
|
25873
25541
|
if (!external_node_worker_threads_namespaceObject.isMainThread) {
|
|
25874
25542
|
Logger.configureAll(process.env.JAM_LOG ?? "", Level.LOG);
|
|
@@ -25877,6 +25545,17 @@ if (!external_node_worker_threads_namespaceObject.isMainThread) {
|
|
|
25877
25545
|
channel.then((channel) => main(channel)).catch((e) => importer_logger.error(e));
|
|
25878
25546
|
}
|
|
25879
25547
|
const keccakHasher = KeccakHasher.create();
|
|
25548
|
+
async function createImporter(config) {
|
|
25549
|
+
const lmdb = new LmdbRoot(config.dbPath);
|
|
25550
|
+
const blocks = new LmdbBlocks(config.chainSpec, lmdb);
|
|
25551
|
+
const states = new LmdbStates(config.chainSpec, lmdb);
|
|
25552
|
+
const hasher = new TransitionHasher(config.chainSpec, await keccakHasher, new allocator_SimpleAllocator());
|
|
25553
|
+
const importer = new Importer(config.chainSpec, hasher, importer_logger, blocks, states);
|
|
25554
|
+
return {
|
|
25555
|
+
lmdb,
|
|
25556
|
+
importer,
|
|
25557
|
+
};
|
|
25558
|
+
}
|
|
25880
25559
|
/**
|
|
25881
25560
|
* The `BlockImporter` listens to `block` signals, where it expects
|
|
25882
25561
|
* RAW undecoded block objects (typically coming from the network).
|
|
@@ -25888,74 +25567,33 @@ async function main(channel) {
|
|
|
25888
25567
|
importer_logger.info(`📥 Importer starting ${channel.currentState()}`);
|
|
25889
25568
|
// Await the configuration object
|
|
25890
25569
|
const ready = await channel.waitForState("ready(importer)");
|
|
25570
|
+
let closeDb = async () => { };
|
|
25891
25571
|
const finished = await ready.doUntil("finished", async (worker, port) => {
|
|
25892
25572
|
const config = worker.getConfig();
|
|
25893
|
-
const lmdb =
|
|
25894
|
-
|
|
25895
|
-
|
|
25896
|
-
|
|
25897
|
-
const importer = new Importer(config.chainSpec, hasher, importer_logger, blocks, states);
|
|
25573
|
+
const { lmdb, importer } = await createImporter(config);
|
|
25574
|
+
closeDb = async () => {
|
|
25575
|
+
await lmdb.close();
|
|
25576
|
+
};
|
|
25898
25577
|
// TODO [ToDr] this is shit, since we have circular dependency.
|
|
25899
25578
|
worker.setImporter(importer);
|
|
25900
25579
|
importer_logger.info("📥 Importer waiting for blocks.");
|
|
25901
|
-
// TODO [ToDr] back pressure?
|
|
25902
|
-
let isProcessing = false;
|
|
25903
|
-
const importingQueue = new ImportQueue(config.chainSpec, importer);
|
|
25904
25580
|
worker.onBlock.on(async (block) => {
|
|
25905
|
-
const
|
|
25906
|
-
|
|
25907
|
-
|
|
25908
|
-
importer_logger.trace("🧊 Ignoring invalid block.");
|
|
25909
|
-
return;
|
|
25910
|
-
}
|
|
25911
|
-
// ignore already known blocks
|
|
25912
|
-
if (blocks.getHeader(details.ok.hash) !== null) {
|
|
25913
|
-
importer_logger.trace(`🧊 Already imported block: #${details.ok.data.timeSlot}.`);
|
|
25914
|
-
return;
|
|
25915
|
-
}
|
|
25916
|
-
const importResult = importingQueue.push(details.ok);
|
|
25917
|
-
// ignore blocks that are already queued
|
|
25918
|
-
if (importResult.isError) {
|
|
25919
|
-
importer_logger.trace(`🧊 Already queued block: #${details.ok.data.timeSlot}.`);
|
|
25920
|
-
return;
|
|
25921
|
-
}
|
|
25922
|
-
importer_logger.log(`🧊 Queued block: #${details.ok.data.timeSlot} (skip seal: ${config.omitSealVerification})`);
|
|
25923
|
-
if (isProcessing) {
|
|
25924
|
-
return;
|
|
25925
|
-
}
|
|
25926
|
-
isProcessing = true;
|
|
25927
|
-
try {
|
|
25928
|
-
for (;;) {
|
|
25929
|
-
const entry = importingQueue.shift();
|
|
25930
|
-
if (entry === undefined) {
|
|
25931
|
-
return;
|
|
25932
|
-
}
|
|
25933
|
-
const { block, seal, timeSlot } = entry;
|
|
25934
|
-
const timer = measure("importBlock");
|
|
25935
|
-
const maybeBestHeader = await importer.importBlock(block, await seal, config.omitSealVerification);
|
|
25936
|
-
if (maybeBestHeader.isOk) {
|
|
25937
|
-
const bestHeader = maybeBestHeader.ok;
|
|
25938
|
-
worker.announce(port, bestHeader);
|
|
25939
|
-
importer_logger.info(`🧊 Best block: #${bestHeader.data.timeSlotIndex.materialize()} (${bestHeader.hash})`);
|
|
25940
|
-
}
|
|
25941
|
-
else {
|
|
25942
|
-
importer_logger.log(`❌ Rejected block #${timeSlot}: ${resultToString(maybeBestHeader)}`);
|
|
25943
|
-
}
|
|
25944
|
-
importer_logger.log(timer());
|
|
25945
|
-
}
|
|
25946
|
-
}
|
|
25947
|
-
finally {
|
|
25948
|
-
isProcessing = false;
|
|
25581
|
+
const res = await importer.importBlock(block, config.omitSealVerification);
|
|
25582
|
+
if (res.isOk) {
|
|
25583
|
+
worker.announce(port, res.ok);
|
|
25949
25584
|
}
|
|
25950
25585
|
});
|
|
25951
25586
|
await wasmPromise;
|
|
25952
25587
|
});
|
|
25953
25588
|
importer_logger.info("📥 Importer finished. Closing channel.");
|
|
25589
|
+
// close the database
|
|
25590
|
+
await closeDb();
|
|
25954
25591
|
// Close the comms to gracefuly close the app.
|
|
25955
25592
|
finished.currentState().close(channel);
|
|
25956
25593
|
}
|
|
25957
25594
|
|
|
25595
|
+
var __webpack_exports__createImporter = __webpack_exports__.F;
|
|
25958
25596
|
var __webpack_exports__main = __webpack_exports__.i;
|
|
25959
|
-
export { __webpack_exports__main as main };
|
|
25597
|
+
export { __webpack_exports__createImporter as createImporter, __webpack_exports__main as main };
|
|
25960
25598
|
|
|
25961
25599
|
//# sourceMappingURL=index.js.map
|