@typeberry/jam 0.0.4 → 0.0.5-0f1acee
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 +18 -7
- package/block-generator/index.js.map +1 -1
- package/importer/index.js +74 -33
- package/importer/index.js.map +1 -1
- package/index.js +136 -120
- package/index.js.map +1 -1
- package/jam-network/index.js +2986 -2970
- package/jam-network/index.js.map +1 -1
- package/package.json +1 -1
package/importer/index.js
CHANGED
|
@@ -9984,6 +9984,7 @@ function legacyServiceNested(serviceId, hash) {
|
|
|
9984
9984
|
;// CONCATENATED MODULE: ./packages/jam/state/accumulation-output.ts
|
|
9985
9985
|
|
|
9986
9986
|
|
|
9987
|
+
|
|
9987
9988
|
/**
|
|
9988
9989
|
* Single service-indexed commitment to accumulation output
|
|
9989
9990
|
*
|
|
@@ -10004,6 +10005,16 @@ class AccumulationOutput {
|
|
|
10004
10005
|
this.output = output;
|
|
10005
10006
|
}
|
|
10006
10007
|
}
|
|
10008
|
+
function accumulationOutputComparator(a, b) {
|
|
10009
|
+
const result = a.serviceId - b.serviceId;
|
|
10010
|
+
if (result < 0) {
|
|
10011
|
+
return Ordering.Less;
|
|
10012
|
+
}
|
|
10013
|
+
if (result > 0) {
|
|
10014
|
+
return Ordering.Greater;
|
|
10015
|
+
}
|
|
10016
|
+
return Ordering.Equal;
|
|
10017
|
+
}
|
|
10007
10018
|
|
|
10008
10019
|
;// CONCATENATED MODULE: ./packages/jam/state/assurances.ts
|
|
10009
10020
|
|
|
@@ -11109,6 +11120,7 @@ class StatisticsData {
|
|
|
11109
11120
|
|
|
11110
11121
|
|
|
11111
11122
|
|
|
11123
|
+
|
|
11112
11124
|
|
|
11113
11125
|
var in_memory_state_UpdateError;
|
|
11114
11126
|
(function (UpdateError) {
|
|
@@ -11512,7 +11524,7 @@ class InMemoryState extends WithDebug {
|
|
|
11512
11524
|
validatorsManager: tryAsServiceId(0),
|
|
11513
11525
|
autoAccumulateServices: [],
|
|
11514
11526
|
}),
|
|
11515
|
-
accumulationOutputLog: [],
|
|
11527
|
+
accumulationOutputLog: SortedArray.fromArray(accumulationOutputComparator, []),
|
|
11516
11528
|
services: new Map(),
|
|
11517
11529
|
});
|
|
11518
11530
|
}
|
|
@@ -11711,7 +11723,7 @@ var serialize;
|
|
|
11711
11723
|
/** C(16): https://graypaper.fluffylabs.dev/#/38c4e62/3b46033b4603?v=0.7.0 */
|
|
11712
11724
|
serialize.accumulationOutputLog = {
|
|
11713
11725
|
key: stateKeys.index(StateKeyIdx.Theta),
|
|
11714
|
-
Codec: descriptors_codec.sequenceVarLen(AccumulationOutput.Codec),
|
|
11726
|
+
Codec: descriptors_codec.sequenceVarLen(AccumulationOutput.Codec).convert((i) => i.array, (o) => SortedArray.fromSortedArray(accumulationOutputComparator, o)),
|
|
11715
11727
|
extract: (s) => s.accumulationOutputLog,
|
|
11716
11728
|
};
|
|
11717
11729
|
/** C(255, s): https://graypaper.fluffylabs.dev/#/85129da/383103383103?v=0.6.3 */
|
|
@@ -13383,7 +13395,6 @@ const GLOBAL_CONFIG = {
|
|
|
13383
13395
|
*/
|
|
13384
13396
|
class Logger {
|
|
13385
13397
|
moduleName;
|
|
13386
|
-
fileName;
|
|
13387
13398
|
config;
|
|
13388
13399
|
/**
|
|
13389
13400
|
* Create a new logger instance given filename and an optional module name.
|
|
@@ -13396,7 +13407,8 @@ class Logger {
|
|
|
13396
13407
|
*/
|
|
13397
13408
|
static new(fileName, moduleName) {
|
|
13398
13409
|
const fName = fileName ?? "unknown";
|
|
13399
|
-
|
|
13410
|
+
const module = moduleName ?? fName;
|
|
13411
|
+
return new Logger(module.padStart(8, " "), GLOBAL_CONFIG);
|
|
13400
13412
|
}
|
|
13401
13413
|
/**
|
|
13402
13414
|
* Return currently configured level for given module. */
|
|
@@ -13433,9 +13445,8 @@ class Logger {
|
|
|
13433
13445
|
const options = parseLoggerOptions(input, defaultLevel, workingDir);
|
|
13434
13446
|
Logger.configureAllFromOptions(options);
|
|
13435
13447
|
}
|
|
13436
|
-
constructor(moduleName,
|
|
13448
|
+
constructor(moduleName, config) {
|
|
13437
13449
|
this.moduleName = moduleName;
|
|
13438
|
-
this.fileName = fileName;
|
|
13439
13450
|
this.config = config;
|
|
13440
13451
|
}
|
|
13441
13452
|
/** Log a message with `INSANE` level. */
|
|
@@ -20155,14 +20166,14 @@ function compareWithEncoding(chainSpec, error, actual, expected, codec) {
|
|
|
20155
20166
|
if (actual === null || expected === null) {
|
|
20156
20167
|
// if one of them is `null`, both need to be.
|
|
20157
20168
|
if (actual !== expected) {
|
|
20158
|
-
return result_Result.error(error,
|
|
20169
|
+
return result_Result.error(error, `${SafroleErrorCode[error]} Expected: ${expected}, got: ${actual}`);
|
|
20159
20170
|
}
|
|
20160
20171
|
return result_Result.ok(result_OK);
|
|
20161
20172
|
}
|
|
20162
20173
|
// compare the literal encoding.
|
|
20163
20174
|
const encoded = encoder_Encoder.encodeObject(codec, actual, chainSpec);
|
|
20164
20175
|
if (!encoded.isEqualTo(expected.encoded())) {
|
|
20165
|
-
return result_Result.error(error,
|
|
20176
|
+
return result_Result.error(error, `${SafroleErrorCode[error]} Expected: ${expected.encoded()}, got: ${encoded}`);
|
|
20166
20177
|
}
|
|
20167
20178
|
return result_Result.ok(result_OK);
|
|
20168
20179
|
}
|
|
@@ -20241,7 +20252,7 @@ class SafroleSeal {
|
|
|
20241
20252
|
const index = timeSlot % keys.length;
|
|
20242
20253
|
const sealingKey = keys[index];
|
|
20243
20254
|
if (!sealingKey.isEqualTo(authorKey.bandersnatch)) {
|
|
20244
|
-
return result_Result.error(SafroleSealError.InvalidValidator, `Expected: ${sealingKey}, got: ${authorKey.bandersnatch}`);
|
|
20255
|
+
return result_Result.error(SafroleSealError.InvalidValidator, `Invalid Validator. Expected: ${sealingKey}, got: ${authorKey.bandersnatch}`);
|
|
20245
20256
|
}
|
|
20246
20257
|
// verify seal correctness
|
|
20247
20258
|
const payload = bytes_BytesBlob.blobFromParts(JAM_FALLBACK_SEAL, entropy.raw);
|
|
@@ -20258,6 +20269,32 @@ class SafroleSeal {
|
|
|
20258
20269
|
|
|
20259
20270
|
|
|
20260
20271
|
|
|
20272
|
+
;// CONCATENATED MODULE: ./packages/jam/transition/accumulate/accumulate-output.ts
|
|
20273
|
+
|
|
20274
|
+
|
|
20275
|
+
|
|
20276
|
+
|
|
20277
|
+
|
|
20278
|
+
class AccumulateOutput {
|
|
20279
|
+
async transition({ accumulationOutputLog }) {
|
|
20280
|
+
const rootHash = await getRootHash(accumulationOutputLog);
|
|
20281
|
+
return rootHash;
|
|
20282
|
+
}
|
|
20283
|
+
}
|
|
20284
|
+
/**
|
|
20285
|
+
* Returns a new root hash
|
|
20286
|
+
*
|
|
20287
|
+
* https://graypaper.fluffylabs.dev/#/38c4e62/3c9d013c9d01?v=0.7.0
|
|
20288
|
+
*/
|
|
20289
|
+
async function getRootHash(yieldedRoots) {
|
|
20290
|
+
const keccakHasher = await KeccakHasher.create();
|
|
20291
|
+
const trieHasher = getKeccakTrieHasher(keccakHasher);
|
|
20292
|
+
const values = yieldedRoots.array.map(({ serviceId, output }) => {
|
|
20293
|
+
return bytes_BytesBlob.blobFromParts([numbers_u32AsLeBytes(serviceId), output.raw]);
|
|
20294
|
+
});
|
|
20295
|
+
return binaryMerkleization(values, trieHasher);
|
|
20296
|
+
}
|
|
20297
|
+
|
|
20261
20298
|
;// CONCATENATED MODULE: ./packages/jam/jam-host-calls/externalities/state-update.ts
|
|
20262
20299
|
|
|
20263
20300
|
|
|
@@ -23352,9 +23389,6 @@ class pvm_executor_PvmExecutor {
|
|
|
23352
23389
|
|
|
23353
23390
|
|
|
23354
23391
|
|
|
23355
|
-
|
|
23356
|
-
|
|
23357
|
-
|
|
23358
23392
|
|
|
23359
23393
|
|
|
23360
23394
|
|
|
@@ -23608,10 +23642,10 @@ class Accumulate {
|
|
|
23608
23642
|
const { services, yieldedRoots, transfers, validatorsData, privilegedServices, authorizationQueues, ...stateUpdateRest } = state;
|
|
23609
23643
|
assertEmpty(stateUpdateRest);
|
|
23610
23644
|
const accStateUpdate = this.getAccumulationStateUpdate(accumulated, toAccumulateLater, slot, Array.from(statistics.keys()), services);
|
|
23611
|
-
const
|
|
23645
|
+
const accumulationOutputUnsorted = Array.from(yieldedRoots.entries()).map(([serviceId, root]) => {
|
|
23612
23646
|
return { serviceId, output: root.asOpaque() };
|
|
23613
23647
|
});
|
|
23614
|
-
const
|
|
23648
|
+
const accumulationOutput = SortedArray.fromArray(accumulationOutputComparator, accumulationOutputUnsorted);
|
|
23615
23649
|
const authQueues = (() => {
|
|
23616
23650
|
if (authorizationQueues.size === 0) {
|
|
23617
23651
|
return {};
|
|
@@ -23623,7 +23657,6 @@ class Accumulate {
|
|
|
23623
23657
|
return { authQueues: tryAsPerCore(updatedAuthQueues, this.chainSpec) };
|
|
23624
23658
|
})();
|
|
23625
23659
|
return result_Result.ok({
|
|
23626
|
-
root: rootHash,
|
|
23627
23660
|
stateUpdate: {
|
|
23628
23661
|
...accStateUpdate,
|
|
23629
23662
|
...(validatorsData === null ? {} : { designatedValidatorData: validatorsData }),
|
|
@@ -23636,20 +23669,6 @@ class Accumulate {
|
|
|
23636
23669
|
});
|
|
23637
23670
|
}
|
|
23638
23671
|
}
|
|
23639
|
-
/**
|
|
23640
|
-
* Returns a new root hash
|
|
23641
|
-
*
|
|
23642
|
-
* https://graypaper.fluffylabs.dev/#/38c4e62/3c9d013c9d01?v=0.7.0
|
|
23643
|
-
*/
|
|
23644
|
-
async function getRootHash(yieldedRoots) {
|
|
23645
|
-
const keccakHasher = await KeccakHasher.create();
|
|
23646
|
-
const trieHasher = getKeccakTrieHasher(keccakHasher);
|
|
23647
|
-
const yieldedRootsSortedByServiceId = yieldedRoots.sort((a, b) => a.serviceId - b.serviceId);
|
|
23648
|
-
const values = yieldedRootsSortedByServiceId.map(({ serviceId, output }) => {
|
|
23649
|
-
return bytes_BytesBlob.blobFromParts([numbers_u32AsLeBytes(serviceId), output.raw]);
|
|
23650
|
-
});
|
|
23651
|
-
return binaryMerkleization(values, trieHasher);
|
|
23652
|
-
}
|
|
23653
23672
|
|
|
23654
23673
|
;// CONCATENATED MODULE: ./packages/jam/transition/accumulate/deferred-transfers.ts
|
|
23655
23674
|
|
|
@@ -25045,6 +25064,7 @@ class Statistics {
|
|
|
25045
25064
|
|
|
25046
25065
|
|
|
25047
25066
|
|
|
25067
|
+
|
|
25048
25068
|
class DbHeaderChain {
|
|
25049
25069
|
blocks;
|
|
25050
25070
|
constructor(blocks) {
|
|
@@ -25088,6 +25108,7 @@ class OnChain {
|
|
|
25088
25108
|
assurances;
|
|
25089
25109
|
// chapter 12: https://graypaper.fluffylabs.dev/#/68eaa1f/159f02159f02?v=0.6.4
|
|
25090
25110
|
accumulate;
|
|
25111
|
+
accumulateOutput;
|
|
25091
25112
|
// chapter 12.3: https://graypaper.fluffylabs.dev/#/68eaa1f/178203178203?v=0.6.4
|
|
25092
25113
|
deferredTransfers;
|
|
25093
25114
|
// chapter 12.4: https://graypaper.fluffylabs.dev/#/68eaa1f/18cc0018cc00?v=0.6.4
|
|
@@ -25112,6 +25133,7 @@ class OnChain {
|
|
|
25112
25133
|
this.reports = new Reports(chainSpec, state, new DbHeaderChain(blocks));
|
|
25113
25134
|
this.assurances = new Assurances(chainSpec, state);
|
|
25114
25135
|
this.accumulate = new Accumulate(chainSpec, state);
|
|
25136
|
+
this.accumulateOutput = new AccumulateOutput();
|
|
25115
25137
|
this.deferredTransfers = new DeferredTransfers(chainSpec, state);
|
|
25116
25138
|
this.preimages = new Preimages(state);
|
|
25117
25139
|
this.authorization = new Authorization(chainSpec, state);
|
|
@@ -25220,7 +25242,7 @@ class OnChain {
|
|
|
25220
25242
|
if (accumulateResult.isError) {
|
|
25221
25243
|
return stfError(StfErrorKind.Accumulate, accumulateResult);
|
|
25222
25244
|
}
|
|
25223
|
-
const {
|
|
25245
|
+
const { stateUpdate: accumulateUpdate, accumulationStatistics, pendingTransfers, accumulationOutputLog, ...accumulateRest } = accumulateResult.ok;
|
|
25224
25246
|
assertEmpty(accumulateRest);
|
|
25225
25247
|
const { privilegedServices: maybePrivilegedServices, authQueues: maybeAuthorizationQueues, designatedValidatorData: maybeDesignatedValidatorData, preimages: accumulatePreimages, accumulationQueue, recentlyAccumulated, ...servicesUpdate } = accumulateUpdate;
|
|
25226
25248
|
const deferredTransfersResult = await this.deferredTransfers.transition({
|
|
@@ -25234,8 +25256,9 @@ class OnChain {
|
|
|
25234
25256
|
}
|
|
25235
25257
|
const { servicesUpdate: newServicesUpdate, transferStatistics, ...deferredTransfersRest } = deferredTransfersResult.ok;
|
|
25236
25258
|
assertEmpty(deferredTransfersRest);
|
|
25259
|
+
const accumulateRoot = await this.accumulateOutput.transition({ accumulationOutputLog });
|
|
25237
25260
|
// recent history
|
|
25238
|
-
const recentHistoryUpdate = this.recentHistory.transition({
|
|
25261
|
+
const recentHistoryUpdate = await this.recentHistory.transition({
|
|
25239
25262
|
partial: recentHistoryPartialUpdate,
|
|
25240
25263
|
headerHash,
|
|
25241
25264
|
accumulateRoot,
|
|
@@ -25330,6 +25353,8 @@ class Importer {
|
|
|
25330
25353
|
stf;
|
|
25331
25354
|
// TODO [ToDr] we cannot assume state reference does not change.
|
|
25332
25355
|
state;
|
|
25356
|
+
// Hash of the block that we have the posterior state for in `state`.
|
|
25357
|
+
currentHash;
|
|
25333
25358
|
constructor(spec, hasher, logger, blocks, states) {
|
|
25334
25359
|
this.logger = logger;
|
|
25335
25360
|
this.blocks = blocks;
|
|
@@ -25342,6 +25367,7 @@ class Importer {
|
|
|
25342
25367
|
this.verifier = new BlockVerifier(hasher, blocks);
|
|
25343
25368
|
this.stf = new OnChain(spec, state, blocks, hasher, { enableParallelSealVerification: true });
|
|
25344
25369
|
this.state = state;
|
|
25370
|
+
this.currentHash = currentBestHeaderHash;
|
|
25345
25371
|
logger.info(`😎 Best time slot: ${state.timeslot} (header hash: ${currentBestHeaderHash})`);
|
|
25346
25372
|
}
|
|
25347
25373
|
/** Attempt to pre-verify the seal to speed up importing. */
|
|
@@ -25368,6 +25394,20 @@ class Importer {
|
|
|
25368
25394
|
if (hash.isError) {
|
|
25369
25395
|
return importerError(ImporterErrorKind.Verifier, hash);
|
|
25370
25396
|
}
|
|
25397
|
+
// TODO [ToDr] This is incomplete/temporary fork support!
|
|
25398
|
+
const parentHash = block.header.view().parentHeaderHash.materialize();
|
|
25399
|
+
if (!this.currentHash.isEqualTo(parentHash)) {
|
|
25400
|
+
const state = this.states.getState(parentHash);
|
|
25401
|
+
if (state === null) {
|
|
25402
|
+
const e = result_Result.error(BlockVerifierError.StateRootNotFound);
|
|
25403
|
+
if (!e.isError) {
|
|
25404
|
+
throw new Error("unreachable, just adding to make compiler happy");
|
|
25405
|
+
}
|
|
25406
|
+
return importerError(ImporterErrorKind.Verifier, e);
|
|
25407
|
+
}
|
|
25408
|
+
this.state.updateBackend(state?.backend);
|
|
25409
|
+
this.currentHash = parentHash;
|
|
25410
|
+
}
|
|
25371
25411
|
const timeSlot = block.header.view().timeSlotIndex.materialize();
|
|
25372
25412
|
const headerHash = hash.ok;
|
|
25373
25413
|
logger.log(`🧱 Verified block: Got hash ${headerHash} for block at slot ${timeSlot}.`);
|
|
@@ -25392,6 +25432,7 @@ class Importer {
|
|
|
25392
25432
|
// TODO [ToDr] This is a temporary measure. We should rather read
|
|
25393
25433
|
// the state of a parent block to support forks and create a fresh STF.
|
|
25394
25434
|
this.state.updateBackend(newState.backend);
|
|
25435
|
+
this.currentHash = headerHash;
|
|
25395
25436
|
logger.log(timerState());
|
|
25396
25437
|
// insert new state and the block to DB.
|
|
25397
25438
|
const timerDb = measure("import:db");
|
|
@@ -25697,7 +25738,7 @@ class ImporterReady extends State {
|
|
|
25697
25738
|
const timeSlot = headerView.timeSlotIndex.materialize();
|
|
25698
25739
|
let response;
|
|
25699
25740
|
try {
|
|
25700
|
-
const res = await this.importer.importBlock(blockView, null);
|
|
25741
|
+
const res = await this.importer.importBlock(blockView, null, config.omitSealVerification);
|
|
25701
25742
|
if (res.isOk) {
|
|
25702
25743
|
state_machine_logger.info(`🧊 Best block: #${timeSlot} (${res.ok.hash})`);
|
|
25703
25744
|
response = result_Result.ok(this.importer.getBestStateRootHash() ?? bytes_Bytes.zero(hash_HASH_SIZE).asOpaque());
|
|
@@ -25803,7 +25844,7 @@ async function main(channel) {
|
|
|
25803
25844
|
importer_logger.trace(`🧊 Already queued block: #${details.ok.data.timeSlot}.`);
|
|
25804
25845
|
return;
|
|
25805
25846
|
}
|
|
25806
|
-
importer_logger.log(`🧊 Queued block: #${details.ok.data.timeSlot}`);
|
|
25847
|
+
importer_logger.log(`🧊 Queued block: #${details.ok.data.timeSlot} (skip seal: ${config.omitSealVerification})`);
|
|
25807
25848
|
if (isProcessing) {
|
|
25808
25849
|
return;
|
|
25809
25850
|
}
|