@typeberry/lib 0.1.3-af70ed0 → 0.1.3-b635981

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/index.cjs +401 -1119
  2. package/index.d.ts +309 -404
  3. package/index.js +400 -1118
  4. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -420,6 +420,20 @@ declare const Result$2 = {
420
420
  },
421
421
  };
422
422
 
423
+ // about 2GB, the maximum ArrayBuffer length on Chrome confirmed by several sources:
424
+ // - https://issues.chromium.org/issues/40055619
425
+ // - https://stackoverflow.com/a/72124984
426
+ // - https://onnxruntime.ai/docs/tutorials/web/large-models.html#maximum-size-of-arraybuffer
427
+ declare const MAX_LENGTH$1 = 2145386496;
428
+
429
+ declare function safeAllocUint8Array(length: number) {
430
+ if (length > MAX_LENGTH) {
431
+ // biome-ignore lint/suspicious/noConsole: can't have a dependency on logger here
432
+ console.warn(`Trying to allocate ${length} bytes, which is greater than the maximum of ${MAX_LENGTH}.`);
433
+ }
434
+ return new Uint8Array(Math.min(MAX_LENGTH, length));
435
+ }
436
+
423
437
  /**
424
438
  * Utilities for tests.
425
439
  */
@@ -755,11 +769,12 @@ declare const index$u_oomWarningPrinted: typeof oomWarningPrinted;
755
769
  declare const index$u_parseCurrentSuite: typeof parseCurrentSuite;
756
770
  declare const index$u_parseCurrentVersion: typeof parseCurrentVersion;
757
771
  declare const index$u_resultToString: typeof resultToString;
772
+ declare const index$u_safeAllocUint8Array: typeof safeAllocUint8Array;
758
773
  declare const index$u_seeThrough: typeof seeThrough;
759
774
  declare const index$u_trimStack: typeof trimStack;
760
775
  declare const index$u_workspacePathFix: typeof workspacePathFix;
761
776
  declare namespace index$u {
762
- export { index$u_ALL_VERSIONS_IN_ORDER as ALL_VERSIONS_IN_ORDER, index$u_CURRENT_SUITE as CURRENT_SUITE, index$u_CURRENT_VERSION as CURRENT_VERSION, index$u_Compatibility as Compatibility, index$u_DEFAULT_SUITE as DEFAULT_SUITE, index$u_DEFAULT_VERSION as DEFAULT_VERSION, index$u_ErrorsCollector as ErrorsCollector, index$u_GpVersion as GpVersion, Result$2 as Result, index$u_RichTaggedError as RichTaggedError, index$u_TEST_COMPARE_USING as TEST_COMPARE_USING, index$u_TestSuite as TestSuite, index$u_WithDebug as WithDebug, index$u___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$u_asOpaqueType as asOpaqueType, index$u_assertEmpty as assertEmpty, index$u_assertNever as assertNever, index$u_callCompareFunction as callCompareFunction, index$u_check as check, index$u_deepEqual as deepEqual, index$u_getAllKeysSorted as getAllKeysSorted, index$u_inspect as inspect, index$u_isBrowser as isBrowser, index$u_isResult as isResult, index$u_isTaggedError as isTaggedError, index$u_maybeTaggedErrorToString as maybeTaggedErrorToString, index$u_measure as measure, index$u_oomWarningPrinted as oomWarningPrinted, index$u_parseCurrentSuite as parseCurrentSuite, index$u_parseCurrentVersion as parseCurrentVersion, index$u_resultToString as resultToString, index$u_seeThrough as seeThrough, index$u_trimStack as trimStack, index$u_workspacePathFix as workspacePathFix };
777
+ export { index$u_ALL_VERSIONS_IN_ORDER as ALL_VERSIONS_IN_ORDER, index$u_CURRENT_SUITE as CURRENT_SUITE, index$u_CURRENT_VERSION as CURRENT_VERSION, index$u_Compatibility as Compatibility, index$u_DEFAULT_SUITE as DEFAULT_SUITE, index$u_DEFAULT_VERSION as DEFAULT_VERSION, index$u_ErrorsCollector as ErrorsCollector, index$u_GpVersion as GpVersion, MAX_LENGTH$1 as MAX_LENGTH, Result$2 as Result, index$u_RichTaggedError as RichTaggedError, index$u_TEST_COMPARE_USING as TEST_COMPARE_USING, index$u_TestSuite as TestSuite, index$u_WithDebug as WithDebug, index$u___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$u_asOpaqueType as asOpaqueType, index$u_assertEmpty as assertEmpty, index$u_assertNever as assertNever, index$u_callCompareFunction as callCompareFunction, index$u_check as check, index$u_deepEqual as deepEqual, index$u_getAllKeysSorted as getAllKeysSorted, index$u_inspect as inspect, index$u_isBrowser as isBrowser, index$u_isResult as isResult, index$u_isTaggedError as isTaggedError, index$u_maybeTaggedErrorToString as maybeTaggedErrorToString, index$u_measure as measure, index$u_oomWarningPrinted as oomWarningPrinted, index$u_parseCurrentSuite as parseCurrentSuite, index$u_parseCurrentVersion as parseCurrentVersion, index$u_resultToString as resultToString, index$u_safeAllocUint8Array as safeAllocUint8Array, index$u_seeThrough as seeThrough, index$u_trimStack as trimStack, index$u_workspacePathFix as workspacePathFix };
763
778
  export type { index$u_DeepEqualOptions as DeepEqualOptions, index$u_EnumMapping as EnumMapping, index$u_ErrorResult as ErrorResult, index$u_OK as OK, index$u_OkResult as OkResult, index$u_Opaque as Opaque, index$u_StringLiteral as StringLiteral, index$u_TaggedError as TaggedError, index$u_TokenOf as TokenOf, index$u_Uninstantiable as Uninstantiable, index$u_WithOpaque as WithOpaque };
764
779
  }
765
780
 
@@ -929,7 +944,7 @@ declare class BytesBlob {
929
944
  static blobFromParts(v: Uint8Array | Uint8Array[], ...rest: Uint8Array[]) {
930
945
  const vArr = v instanceof Uint8Array ? [v] : v;
931
946
  const totalLength = vArr.reduce((a, v) => a + v.length, 0) + rest.reduce((a, v) => a + v.length, 0);
932
- const buffer = new Uint8Array(totalLength);
947
+ const buffer = safeAllocUint8Array(totalLength);
933
948
  let offset = 0;
934
949
  for (const r of vArr) {
935
950
  buffer.set(r, offset);
@@ -1012,7 +1027,7 @@ declare class Bytes<T extends number> extends BytesBlob {
1012
1027
 
1013
1028
  /** Create an empty [`Bytes<X>`] of given length. */
1014
1029
  static zero<X extends number>(len: X): Bytes<X> {
1015
- return new Bytes(new Uint8Array(len), len);
1030
+ return new Bytes(safeAllocUint8Array(len), len);
1016
1031
  }
1017
1032
 
1018
1033
  // TODO [ToDr] `fill` should have the argments swapped to align with the rest.
@@ -1133,7 +1148,7 @@ declare class BitVec {
1133
1148
  * Create new [`BitVec`] with all values set to `false`.
1134
1149
  */
1135
1150
  static empty(bitLength: number) {
1136
- const data = new Uint8Array(Math.ceil(bitLength / 8));
1151
+ const data = safeAllocUint8Array(Math.ceil(bitLength / 8));
1137
1152
  return new BitVec(data, bitLength);
1138
1153
  }
1139
1154
 
@@ -3461,6 +3476,99 @@ declare namespace index$q {
3461
3476
  export type { index$q_ClassConstructor as ClassConstructor, index$q_Codec as Codec, index$q_CodecRecord as CodecRecord, index$q_Decode as Decode, index$q_DescribedBy as DescribedBy, index$q_DescriptorRecord as DescriptorRecord, index$q_Encode as Encode, index$q_LengthRange as LengthRange, index$q_OptionalRecord as OptionalRecord, Options$1 as Options, index$q_PropertyKeys as PropertyKeys, index$q_SimpleDescriptorRecord as SimpleDescriptorRecord, index$q_SizeHint as SizeHint, index$q_ViewOf as ViewOf };
3462
3477
  }
3463
3478
 
3479
+ /**
3480
+ * A utility class providing a readonly view over a portion of an array without copying it.
3481
+ */
3482
+ declare class ArrayView<T> implements Iterable<T> {
3483
+ private readonly source: T[];
3484
+ public readonly length: number;
3485
+
3486
+ private constructor(
3487
+ source: T[],
3488
+ private readonly start: number,
3489
+ private readonly end: number,
3490
+ ) {
3491
+ this.source = source;
3492
+ this.length = end - start;
3493
+ }
3494
+
3495
+ static from<T>(source: T[], start = 0, end = source.length): ArrayView<T> {
3496
+ check`
3497
+ ${start >= 0 && end <= source.length && start <= end}
3498
+ Invalid start (${start})/end (${end}) for ArrayView
3499
+ `;
3500
+ return new ArrayView(source, start, end);
3501
+ }
3502
+
3503
+ get(i: number): T {
3504
+ check`
3505
+ ${i >= 0 && i < this.length}
3506
+ Index out of bounds: ${i} < ${this.length}
3507
+ `;
3508
+ return this.source[this.start + i];
3509
+ }
3510
+
3511
+ subview(from: number, to: number = this.length): ArrayView<T> {
3512
+ return ArrayView.from(this.source, this.start + from, this.start + to);
3513
+ }
3514
+
3515
+ toArray(): T[] {
3516
+ return this.source.slice(this.start, this.end);
3517
+ }
3518
+
3519
+ *[Symbol.iterator](): Iterator<T> {
3520
+ for (let i = this.start; i < this.end; i++) {
3521
+ yield this.source[i];
3522
+ }
3523
+ }
3524
+ }
3525
+
3526
+ type ITypedArray = Uint8Array | Uint16Array | Uint32Array;
3527
+ type IDataType = string | Buffer | ITypedArray;
3528
+
3529
+ type IHasher = {
3530
+ /**
3531
+ * Initializes hash state to default value
3532
+ */
3533
+ init: () => IHasher;
3534
+ /**
3535
+ * Updates the hash content with the given data
3536
+ */
3537
+ update: (data: IDataType) => IHasher;
3538
+ /**
3539
+ * Calculates the hash of all of the data passed to be hashed with hash.update().
3540
+ * Defaults to hexadecimal string
3541
+ * @param outputType If outputType is "binary", it returns Uint8Array. Otherwise it
3542
+ * returns hexadecimal string
3543
+ */
3544
+ digest: {
3545
+ (outputType: "binary"): Uint8Array;
3546
+ (outputType?: "hex"): string;
3547
+ };
3548
+ /**
3549
+ * Save the current internal state of the hasher for later resumption with load().
3550
+ * Cannot be called before .init() or after .digest()
3551
+ *
3552
+ * Note that this state can include arbitrary information about the value being hashed (e.g.
3553
+ * could include N plaintext bytes from the value), so needs to be treated as being as
3554
+ * sensitive as the input value itself.
3555
+ */
3556
+ save: () => Uint8Array;
3557
+ /**
3558
+ * Resume a state that was created by save(). If this state was not created by a
3559
+ * compatible build of hash-wasm, an exception will be thrown.
3560
+ */
3561
+ load: (state: Uint8Array) => IHasher;
3562
+ /**
3563
+ * Block size in bytes
3564
+ */
3565
+ blockSize: number;
3566
+ /**
3567
+ * Digest size in bytes
3568
+ */
3569
+ digestSize: number;
3570
+ };
3571
+
3464
3572
  /**
3465
3573
  * Size of the output of the hash functions.
3466
3574
  *
@@ -3516,144 +3624,46 @@ declare class WithHashAndBytes<THash extends OpaqueHash, TData> extends WithHash
3516
3624
  }
3517
3625
  }
3518
3626
 
3519
- /** Allocator interface - returns an empty bytes vector that can be filled with the hash. */
3520
- interface HashAllocator {
3521
- /** Return a new hash destination. */
3522
- emptyHash(): OpaqueHash;
3523
- }
3524
-
3525
- /** The simplest allocator returning just a fresh copy of bytes each time. */
3526
- declare class SimpleAllocator implements HashAllocator {
3527
- emptyHash(): OpaqueHash {
3528
- return Bytes.zero(HASH_SIZE);
3529
- }
3530
- }
3531
-
3532
- /** An allocator that works by allocating larger (continuous) pages of memory. */
3533
- declare class PageAllocator implements HashAllocator {
3534
- private page: Uint8Array = new Uint8Array(0);
3535
- private currentHash = 0;
3627
+ declare const zero$1 = Bytes.zero(HASH_SIZE);
3536
3628
 
3537
- // TODO [ToDr] Benchmark the performance!
3538
- constructor(private readonly hashesPerPage: number) {
3539
- check`${hashesPerPage > 0 && hashesPerPage >>> 0 === hashesPerPage} Expected a non-zero integer.`;
3540
- this.resetPage();
3629
+ declare class Blake2b {
3630
+ static async createHasher() {
3631
+ return new Blake2b(await createBLAKE2b(HASH_SIZE * 8));
3541
3632
  }
3542
3633
 
3543
- private resetPage() {
3544
- const pageSizeBytes = this.hashesPerPage * HASH_SIZE;
3545
- this.currentHash = 0;
3546
- this.page = new Uint8Array(pageSizeBytes);
3547
- }
3548
-
3549
- emptyHash(): OpaqueHash {
3550
- const startIdx = this.currentHash * HASH_SIZE;
3551
- const endIdx = startIdx + HASH_SIZE;
3634
+ private constructor(private readonly hasher: IHasher) {}
3552
3635
 
3553
- this.currentHash += 1;
3554
- if (this.currentHash >= this.hashesPerPage) {
3555
- this.resetPage();
3636
+ /**
3637
+ * Hash given collection of blobs.
3638
+ *
3639
+ * If empty array is given a zero-hash is returned.
3640
+ */
3641
+ hashBlobs<H extends Blake2bHash>(r: (BytesBlob | Uint8Array)[]): H {
3642
+ if (r.length === 0) {
3643
+ return zero.asOpaque();
3556
3644
  }
3557
3645
 
3558
- return Bytes.fromBlob(this.page.subarray(startIdx, endIdx), HASH_SIZE);
3646
+ const hasher = this.hasher.init();
3647
+ for (const v of r) {
3648
+ hasher.update(v instanceof BytesBlob ? v.raw : v);
3649
+ }
3650
+ return Bytes.fromBlob(hasher.digest("binary"), HASH_SIZE).asOpaque();
3559
3651
  }
3560
- }
3561
3652
 
3562
- declare const defaultAllocator = new SimpleAllocator();
3563
-
3564
- /**
3565
- * Hash given collection of blobs.
3566
- *
3567
- * If empty array is given a zero-hash is returned.
3568
- */
3569
- declare function hashBlobs$1<H extends Blake2bHash>(
3570
- r: (BytesBlob | Uint8Array)[],
3571
- allocator: HashAllocator = defaultAllocator,
3572
- ): H {
3573
- const out = allocator.emptyHash();
3574
- if (r.length === 0) {
3575
- return out.asOpaque();
3653
+ /** Hash given blob of bytes. */
3654
+ hashBytes(blob: BytesBlob | Uint8Array): Blake2bHash {
3655
+ const hasher = this.hasher.init();
3656
+ const bytes = blob instanceof BytesBlob ? blob.raw : blob;
3657
+ hasher.update(bytes);
3658
+ return Bytes.fromBlob(hasher.digest("binary"), HASH_SIZE).asOpaque();
3576
3659
  }
3577
3660
 
3578
- const hasher = blake2b(HASH_SIZE);
3579
- for (const v of r) {
3580
- hasher?.update(v instanceof BytesBlob ? v.raw : v);
3661
+ /** Convert given string into bytes and hash it. */
3662
+ hashString(str: string) {
3663
+ return this.hashBytes(BytesBlob.blobFromString(str));
3581
3664
  }
3582
- hasher?.digest(out.raw);
3583
- return out.asOpaque();
3584
- }
3585
-
3586
- /** Hash given blob of bytes. */
3587
- declare function hashBytes(blob: BytesBlob | Uint8Array, allocator: HashAllocator = defaultAllocator): Blake2bHash {
3588
- const hasher = blake2b(HASH_SIZE);
3589
- const bytes = blob instanceof BytesBlob ? blob.raw : blob;
3590
- hasher?.update(bytes);
3591
- const out = allocator.emptyHash();
3592
- hasher?.digest(out.raw);
3593
- return out;
3594
- }
3595
-
3596
- /** Convert given string into bytes and hash it. */
3597
- declare function hashString(str: string, allocator: HashAllocator = defaultAllocator) {
3598
- return hashBytes(BytesBlob.blobFromString(str), allocator);
3599
3665
  }
3600
3666
 
3601
- declare const blake2b_hashBytes: typeof hashBytes;
3602
- declare const blake2b_hashString: typeof hashString;
3603
- declare namespace blake2b {
3604
- export {
3605
- hashBlobs$1 as hashBlobs,
3606
- blake2b_hashBytes as hashBytes,
3607
- blake2b_hashString as hashString,
3608
- };
3609
- }
3610
-
3611
- type ITypedArray = Uint8Array | Uint16Array | Uint32Array;
3612
- type IDataType = string | Buffer | ITypedArray;
3613
-
3614
- type IHasher = {
3615
- /**
3616
- * Initializes hash state to default value
3617
- */
3618
- init: () => IHasher;
3619
- /**
3620
- * Updates the hash content with the given data
3621
- */
3622
- update: (data: IDataType) => IHasher;
3623
- /**
3624
- * Calculates the hash of all of the data passed to be hashed with hash.update().
3625
- * Defaults to hexadecimal string
3626
- * @param outputType If outputType is "binary", it returns Uint8Array. Otherwise it
3627
- * returns hexadecimal string
3628
- */
3629
- digest: {
3630
- (outputType: "binary"): Uint8Array;
3631
- (outputType?: "hex"): string;
3632
- };
3633
- /**
3634
- * Save the current internal state of the hasher for later resumption with load().
3635
- * Cannot be called before .init() or after .digest()
3636
- *
3637
- * Note that this state can include arbitrary information about the value being hashed (e.g.
3638
- * could include N plaintext bytes from the value), so needs to be treated as being as
3639
- * sensitive as the input value itself.
3640
- */
3641
- save: () => Uint8Array;
3642
- /**
3643
- * Resume a state that was created by save(). If this state was not created by a
3644
- * compatible build of hash-wasm, an exception will be thrown.
3645
- */
3646
- load: (state: Uint8Array) => IHasher;
3647
- /**
3648
- * Block size in bytes
3649
- */
3650
- blockSize: number;
3651
- /**
3652
- * Digest size in bytes
3653
- */
3654
- digestSize: number;
3655
- };
3656
-
3657
3667
  declare class KeccakHasher {
3658
3668
  static async create(): Promise<KeccakHasher> {
3659
3669
  return new KeccakHasher(await createKeccak(256));
@@ -3681,15 +3691,15 @@ declare namespace keccak {
3681
3691
  };
3682
3692
  }
3683
3693
 
3694
+ // TODO [ToDr] (#213) this should most likely be moved to a separate
3695
+ // package to avoid pulling in unnecessary deps.
3696
+
3697
+ type index$p_Blake2b = Blake2b;
3698
+ declare const index$p_Blake2b: typeof Blake2b;
3684
3699
  type index$p_Blake2bHash = Blake2bHash;
3685
3700
  type index$p_HASH_SIZE = HASH_SIZE;
3686
- type index$p_HashAllocator = HashAllocator;
3687
3701
  type index$p_KeccakHash = KeccakHash;
3688
3702
  type index$p_OpaqueHash = OpaqueHash;
3689
- type index$p_PageAllocator = PageAllocator;
3690
- declare const index$p_PageAllocator: typeof PageAllocator;
3691
- type index$p_SimpleAllocator = SimpleAllocator;
3692
- declare const index$p_SimpleAllocator: typeof SimpleAllocator;
3693
3703
  type index$p_TRUNCATED_HASH_SIZE = TRUNCATED_HASH_SIZE;
3694
3704
  type index$p_TruncatedHash = TruncatedHash;
3695
3705
  type index$p_WithHash<THash extends OpaqueHash, TData> = WithHash<THash, TData>;
@@ -3697,12 +3707,10 @@ declare const index$p_WithHash: typeof WithHash;
3697
3707
  type index$p_WithHashAndBytes<THash extends OpaqueHash, TData> = WithHashAndBytes<THash, TData>;
3698
3708
  declare const index$p_WithHashAndBytes: typeof WithHashAndBytes;
3699
3709
  declare const index$p_ZERO_HASH: typeof ZERO_HASH;
3700
- declare const index$p_blake2b: typeof blake2b;
3701
- declare const index$p_defaultAllocator: typeof defaultAllocator;
3702
3710
  declare const index$p_keccak: typeof keccak;
3703
3711
  declare namespace index$p {
3704
- export { index$p_PageAllocator as PageAllocator, index$p_SimpleAllocator as SimpleAllocator, index$p_WithHash as WithHash, index$p_WithHashAndBytes as WithHashAndBytes, index$p_ZERO_HASH as ZERO_HASH, index$p_blake2b as blake2b, index$p_defaultAllocator as defaultAllocator, index$p_keccak as keccak };
3705
- export type { index$p_Blake2bHash as Blake2bHash, index$p_HASH_SIZE as HASH_SIZE, index$p_HashAllocator as HashAllocator, index$p_KeccakHash as KeccakHash, index$p_OpaqueHash as OpaqueHash, index$p_TRUNCATED_HASH_SIZE as TRUNCATED_HASH_SIZE, index$p_TruncatedHash as TruncatedHash };
3712
+ export { index$p_Blake2b as Blake2b, index$p_WithHash as WithHash, index$p_WithHashAndBytes as WithHashAndBytes, index$p_ZERO_HASH as ZERO_HASH, index$p_keccak as keccak, zero$1 as zero };
3713
+ export type { index$p_Blake2bHash as Blake2bHash, index$p_HASH_SIZE as HASH_SIZE, index$p_KeccakHash as KeccakHash, index$p_OpaqueHash as OpaqueHash, index$p_TRUNCATED_HASH_SIZE as TRUNCATED_HASH_SIZE, index$p_TruncatedHash as TruncatedHash };
3706
3714
  }
3707
3715
 
3708
3716
  /** Immutable view of the `HashDictionary`. */
@@ -4479,6 +4487,8 @@ declare class TruncatedHashDictionary<T extends OpaqueHash, V> {
4479
4487
  }
4480
4488
  }
4481
4489
 
4490
+ type index$o_ArrayView<T> = ArrayView<T>;
4491
+ declare const index$o_ArrayView: typeof ArrayView;
4482
4492
  type index$o_FixedSizeArray<T, N extends number> = FixedSizeArray<T, N>;
4483
4493
  declare const index$o_FixedSizeArray: typeof FixedSizeArray;
4484
4494
  type index$o_HashDictionary<K extends OpaqueHash, V> = HashDictionary<K, V>;
@@ -4506,7 +4516,7 @@ type index$o_TruncatedHashDictionary<T extends OpaqueHash, V> = TruncatedHashDic
4506
4516
  declare const index$o_TruncatedHashDictionary: typeof TruncatedHashDictionary;
4507
4517
  declare const index$o_asKnownSize: typeof asKnownSize;
4508
4518
  declare namespace index$o {
4509
- export { index$o_FixedSizeArray as FixedSizeArray, index$o_HashDictionary as HashDictionary, index$o_HashSet as HashSet, index$o_MultiMap as MultiMap, index$o_SortedArray as SortedArray, index$o_SortedSet as SortedSet, index$o_TruncatedHashDictionary as TruncatedHashDictionary, index$o_asKnownSize as asKnownSize };
4519
+ export { index$o_ArrayView as ArrayView, index$o_FixedSizeArray as FixedSizeArray, index$o_HashDictionary as HashDictionary, index$o_HashSet as HashSet, index$o_MultiMap as MultiMap, index$o_SortedArray as SortedArray, index$o_SortedSet as SortedSet, index$o_TruncatedHashDictionary as TruncatedHashDictionary, index$o_asKnownSize as asKnownSize };
4510
4520
  export type { index$o_HashWithZeroedBit as HashWithZeroedBit, index$o_ImmutableHashDictionary as ImmutableHashDictionary, index$o_ImmutableHashSet as ImmutableHashSet, index$o_ImmutableSortedArray as ImmutableSortedArray, index$o_ImmutableSortedSet as ImmutableSortedSet, index$o_KeyMapper as KeyMapper, index$o_KeyMappers as KeyMappers, index$o_KnownSize as KnownSize, index$o_KnownSizeArray as KnownSizeArray, index$o_KnownSizeId as KnownSizeId, index$o_NestedMaps as NestedMaps };
4511
4521
  }
4512
4522
 
@@ -4735,7 +4745,7 @@ declare async function verify<T extends BytesBlob>(input: Input<T>[]): Promise<b
4735
4745
  (acc, { message, key, signature }) => acc + key.length + signature.length + message.length + 1,
4736
4746
  0,
4737
4747
  );
4738
- const data = new Uint8Array(dataLength);
4748
+ const data = safeAllocUint8Array(dataLength);
4739
4749
 
4740
4750
  let offset = 0;
4741
4751
 
@@ -4825,22 +4835,16 @@ declare function trivialSeed(s: U32): KeySeed {
4825
4835
  * Derives a Ed25519 secret key from a seed.
4826
4836
  * https://github.com/polkadot-fellows/JIPs/blob/7048f79edf4f4eb8bfe6fb42e6bbf61900f44c65/JIP-5.md#derivation-method
4827
4837
  */
4828
- declare function deriveEd25519SecretKey(
4829
- seed: KeySeed,
4830
- allocator: SimpleAllocator = new SimpleAllocator(),
4831
- ): Ed25519SecretSeed {
4832
- return blake2b.hashBytes(BytesBlob.blobFromParts([ED25519_SECRET_KEY.raw, seed.raw]), allocator).asOpaque();
4838
+ declare function deriveEd25519SecretKey(seed: KeySeed, blake2b: Blake2b): Ed25519SecretSeed {
4839
+ return blake2b.hashBytes(BytesBlob.blobFromParts([ED25519_SECRET_KEY.raw, seed.raw])).asOpaque();
4833
4840
  }
4834
4841
 
4835
4842
  /**
4836
4843
  * Derives a Bandersnatch secret key from a seed.
4837
4844
  * https://github.com/polkadot-fellows/JIPs/blob/7048f79edf4f4eb8bfe6fb42e6bbf61900f44c65/JIP-5.md#derivation-method
4838
4845
  */
4839
- declare function deriveBandersnatchSecretKey(
4840
- seed: KeySeed,
4841
- allocator: SimpleAllocator = new SimpleAllocator(),
4842
- ): BandersnatchSecretSeed {
4843
- return blake2b.hashBytes(BytesBlob.blobFromParts([BANDERSNATCH_SECRET_KEY.raw, seed.raw]), allocator).asOpaque();
4846
+ declare function deriveBandersnatchSecretKey(seed: KeySeed, blake2b: Blake2b): BandersnatchSecretSeed {
4847
+ return blake2b.hashBytes(BytesBlob.blobFromParts([BANDERSNATCH_SECRET_KEY.raw, seed.raw])).asOpaque();
4844
4848
  }
4845
4849
 
4846
4850
  /**
@@ -8373,7 +8377,7 @@ declare enum NodeType {
8373
8377
  declare class TrieNode {
8374
8378
  constructor(
8375
8379
  /** Exactly 512 bits / 64 bytes */
8376
- public readonly raw: Uint8Array = new Uint8Array(TRIE_NODE_BYTES),
8380
+ public readonly raw: Uint8Array = safeAllocUint8Array(TRIE_NODE_BYTES),
8377
8381
  ) {}
8378
8382
 
8379
8383
  /** Returns the type of the node */
@@ -9111,21 +9115,6 @@ declare function accumulationOutputComparator(a: AccumulationOutput, b: Accumula
9111
9115
  return Ordering.Equal;
9112
9116
  }
9113
9117
 
9114
- declare const codecWithHash = <T, V, H extends OpaqueHash>(val: Descriptor<T, V>): Descriptor<WithHash<H, T>, V> =>
9115
- Descriptor.withView(
9116
- val.name,
9117
- val.sizeHint,
9118
- (e, elem) => val.encode(e, elem.data),
9119
- (d): WithHash<H, T> => {
9120
- const decoder2 = d.clone();
9121
- const encoded = val.skipEncoded(decoder2);
9122
- const hash = blake2b.hashBytes(encoded);
9123
- return new WithHash(hash.asOpaque(), val.decode(d));
9124
- },
9125
- val.skip,
9126
- val.View,
9127
- );
9128
-
9129
9118
  /**
9130
9119
  * Assignment of particular work report to a core.
9131
9120
  *
@@ -9136,7 +9125,7 @@ declare const codecWithHash = <T, V, H extends OpaqueHash>(val: Descriptor<T, V>
9136
9125
  */
9137
9126
  declare class AvailabilityAssignment extends WithDebug {
9138
9127
  static Codec = codec.Class(AvailabilityAssignment, {
9139
- workReport: codecWithHash(WorkReport.Codec),
9128
+ workReport: WorkReport.Codec,
9140
9129
  timeout: codec.u32.asOpaque<TimeSlot>(),
9141
9130
  });
9142
9131
 
@@ -9146,7 +9135,7 @@ declare class AvailabilityAssignment extends WithDebug {
9146
9135
 
9147
9136
  private constructor(
9148
9137
  /** Work report assigned to a core. */
9149
- public readonly workReport: WithHash<WorkReportHash, WorkReport>,
9138
+ public readonly workReport: WorkReport,
9150
9139
  /** Time slot at which the report becomes obsolete. */
9151
9140
  public readonly timeout: TimeSlot,
9152
9141
  ) {
@@ -9834,6 +9823,31 @@ declare const ignoreValueWithDefault = <T>(defaultValue: T) =>
9834
9823
  (_s) => {},
9835
9824
  );
9836
9825
 
9826
+ /** Encode and decode object with leading version number. */
9827
+ declare const codecWithVersion = <T>(val: Descriptor<T>): Descriptor<T> =>
9828
+ Descriptor.new<T>(
9829
+ "withVersion",
9830
+ {
9831
+ bytes: val.sizeHint.bytes + 8,
9832
+ isExact: false,
9833
+ },
9834
+ (e, v) => {
9835
+ e.varU64(0n);
9836
+ val.encode(e, v);
9837
+ },
9838
+ (d) => {
9839
+ const version = d.varU64();
9840
+ if (version !== 0n) {
9841
+ throw new Error("Non-zero version is not supported!");
9842
+ }
9843
+ return val.decode(d);
9844
+ },
9845
+ (s) => {
9846
+ s.varU64();
9847
+ val.skip(s);
9848
+ },
9849
+ );
9850
+
9837
9851
  /**
9838
9852
  * Service account details.
9839
9853
  *
@@ -11293,7 +11307,7 @@ declare const index$e_codecPerCore: typeof codecPerCore;
11293
11307
  declare const index$e_codecServiceId: typeof codecServiceId;
11294
11308
  declare const index$e_codecVarGas: typeof codecVarGas;
11295
11309
  declare const index$e_codecVarU16: typeof codecVarU16;
11296
- declare const index$e_codecWithHash: typeof codecWithHash;
11310
+ declare const index$e_codecWithVersion: typeof codecWithVersion;
11297
11311
  declare const index$e_hashComparator: typeof hashComparator;
11298
11312
  declare const index$e_ignoreValueWithDefault: typeof ignoreValueWithDefault;
11299
11313
  declare const index$e_serviceDataCodec: typeof serviceDataCodec;
@@ -11304,7 +11318,7 @@ declare const index$e_tryAsPerCore: typeof tryAsPerCore;
11304
11318
  declare const index$e_workReportsSortedSetCodec: typeof workReportsSortedSetCodec;
11305
11319
  declare const index$e_zeroSizeHint: typeof zeroSizeHint;
11306
11320
  declare namespace index$e {
11307
- export { index$e_AccumulationOutput as AccumulationOutput, index$e_AutoAccumulate as AutoAccumulate, index$e_AvailabilityAssignment as AvailabilityAssignment, index$e_BASE_SERVICE_BALANCE as BASE_SERVICE_BALANCE, index$e_BlockState as BlockState, index$e_CoreStatistics as CoreStatistics, index$e_DisputesRecords as DisputesRecords, index$e_ELECTIVE_BYTE_BALANCE as ELECTIVE_BYTE_BALANCE, index$e_ELECTIVE_ITEM_BALANCE as ELECTIVE_ITEM_BALANCE, index$e_InMemoryService as InMemoryService, index$e_InMemoryState as InMemoryState, index$e_LookupHistoryItem as LookupHistoryItem, index$e_MAX_LOOKUP_HISTORY_SLOTS as MAX_LOOKUP_HISTORY_SLOTS, index$e_PreimageItem as PreimageItem, index$e_PrivilegedServices as PrivilegedServices, index$e_RecentBlocks as RecentBlocks, index$e_RecentBlocksHistory as RecentBlocksHistory, index$e_SafroleData as SafroleData, index$e_SafroleSealingKeysData as SafroleSealingKeysData, index$e_SafroleSealingKeysKind as SafroleSealingKeysKind, index$e_ServiceAccountInfo as ServiceAccountInfo, index$e_ServiceStatistics as ServiceStatistics, index$e_StatisticsData as StatisticsData, index$e_StorageItem as StorageItem, index$e_UpdateError as UpdateError, index$e_UpdatePreimage as UpdatePreimage, index$e_UpdatePreimageKind as UpdatePreimageKind, index$e_UpdateService as UpdateService, index$e_UpdateServiceKind as UpdateServiceKind, index$e_UpdateStorage as UpdateStorage, index$e_UpdateStorageKind as UpdateStorageKind, index$e_ValidatorData as ValidatorData, index$e_ValidatorStatistics as ValidatorStatistics, index$e_accumulationOutputComparator as accumulationOutputComparator, index$e_codecBandersnatchKey as codecBandersnatchKey, index$e_codecPerCore as codecPerCore, index$e_codecServiceId as codecServiceId, index$e_codecVarGas as codecVarGas, index$e_codecVarU16 as codecVarU16, index$e_codecWithHash as codecWithHash, index$e_hashComparator as hashComparator, index$e_ignoreValueWithDefault as ignoreValueWithDefault, index$e_serviceDataCodec as serviceDataCodec, index$e_serviceEntriesCodec as serviceEntriesCodec, index$e_sortedSetCodec as sortedSetCodec, index$e_tryAsLookupHistorySlots as tryAsLookupHistorySlots, index$e_tryAsPerCore as tryAsPerCore, index$e_workReportsSortedSetCodec as workReportsSortedSetCodec, index$e_zeroSizeHint as zeroSizeHint };
11321
+ export { index$e_AccumulationOutput as AccumulationOutput, index$e_AutoAccumulate as AutoAccumulate, index$e_AvailabilityAssignment as AvailabilityAssignment, index$e_BASE_SERVICE_BALANCE as BASE_SERVICE_BALANCE, index$e_BlockState as BlockState, index$e_CoreStatistics as CoreStatistics, index$e_DisputesRecords as DisputesRecords, index$e_ELECTIVE_BYTE_BALANCE as ELECTIVE_BYTE_BALANCE, index$e_ELECTIVE_ITEM_BALANCE as ELECTIVE_ITEM_BALANCE, index$e_InMemoryService as InMemoryService, index$e_InMemoryState as InMemoryState, index$e_LookupHistoryItem as LookupHistoryItem, index$e_MAX_LOOKUP_HISTORY_SLOTS as MAX_LOOKUP_HISTORY_SLOTS, index$e_PreimageItem as PreimageItem, index$e_PrivilegedServices as PrivilegedServices, index$e_RecentBlocks as RecentBlocks, index$e_RecentBlocksHistory as RecentBlocksHistory, index$e_SafroleData as SafroleData, index$e_SafroleSealingKeysData as SafroleSealingKeysData, index$e_SafroleSealingKeysKind as SafroleSealingKeysKind, index$e_ServiceAccountInfo as ServiceAccountInfo, index$e_ServiceStatistics as ServiceStatistics, index$e_StatisticsData as StatisticsData, index$e_StorageItem as StorageItem, index$e_UpdateError as UpdateError, index$e_UpdatePreimage as UpdatePreimage, index$e_UpdatePreimageKind as UpdatePreimageKind, index$e_UpdateService as UpdateService, index$e_UpdateServiceKind as UpdateServiceKind, index$e_UpdateStorage as UpdateStorage, index$e_UpdateStorageKind as UpdateStorageKind, index$e_ValidatorData as ValidatorData, index$e_ValidatorStatistics as ValidatorStatistics, index$e_accumulationOutputComparator as accumulationOutputComparator, index$e_codecBandersnatchKey as codecBandersnatchKey, index$e_codecPerCore as codecPerCore, index$e_codecServiceId as codecServiceId, index$e_codecVarGas as codecVarGas, index$e_codecVarU16 as codecVarU16, index$e_codecWithVersion as codecWithVersion, index$e_hashComparator as hashComparator, index$e_ignoreValueWithDefault as ignoreValueWithDefault, index$e_serviceDataCodec as serviceDataCodec, index$e_serviceEntriesCodec as serviceEntriesCodec, index$e_sortedSetCodec as sortedSetCodec, index$e_tryAsLookupHistorySlots as tryAsLookupHistorySlots, index$e_tryAsPerCore as tryAsPerCore, index$e_workReportsSortedSetCodec as workReportsSortedSetCodec, index$e_zeroSizeHint as zeroSizeHint };
11308
11322
  export type { index$e_BlocksState as BlocksState, index$e_ENTROPY_ENTRIES as ENTROPY_ENTRIES, index$e_EnumerableState as EnumerableState, index$e_FieldNames as FieldNames, index$e_InMemoryStateFields as InMemoryStateFields, index$e_LookupHistorySlots as LookupHistorySlots, index$e_MAX_RECENT_HISTORY as MAX_RECENT_HISTORY, index$e_PerCore as PerCore, index$e_SafroleSealingKeys as SafroleSealingKeys, index$e_Service as Service, index$e_ServiceData as ServiceData, index$e_ServiceEntries as ServiceEntries, index$e_ServicesUpdate as ServicesUpdate, index$e_State as State, index$e_StorageKey as StorageKey, index$e_VALIDATOR_META_BYTES as VALIDATOR_META_BYTES };
11309
11323
  }
11310
11324
 
@@ -11372,7 +11386,7 @@ declare namespace stateKeys {
11372
11386
  }
11373
11387
 
11374
11388
  /** https://graypaper.fluffylabs.dev/#/1c979cb/3bba033bba03?v=0.7.1 */
11375
- export function serviceStorage(serviceId: ServiceId, key: StorageKey): StateKey {
11389
+ export function serviceStorage(blake2b: Blake2b, serviceId: ServiceId, key: StorageKey): StateKey {
11376
11390
  if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
11377
11391
  const out = Bytes.zero(HASH_SIZE);
11378
11392
  out.raw.set(u32AsLeBytes(tryAsU32(2 ** 32 - 1)), 0);
@@ -11380,11 +11394,11 @@ declare namespace stateKeys {
11380
11394
  return legacyServiceNested(serviceId, out);
11381
11395
  }
11382
11396
 
11383
- return serviceNested(serviceId, tryAsU32(2 ** 32 - 1), key);
11397
+ return serviceNested(blake2b, serviceId, tryAsU32(2 ** 32 - 1), key);
11384
11398
  }
11385
11399
 
11386
11400
  /** https://graypaper.fluffylabs.dev/#/1c979cb/3bd7033bd703?v=0.7.1 */
11387
- export function servicePreimage(serviceId: ServiceId, hash: PreimageHash): StateKey {
11401
+ export function servicePreimage(blake2b: Blake2b, serviceId: ServiceId, hash: PreimageHash): StateKey {
11388
11402
  if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
11389
11403
  const out = Bytes.zero(HASH_SIZE);
11390
11404
  out.raw.set(u32AsLeBytes(tryAsU32(2 ** 32 - 2)), 0);
@@ -11392,11 +11406,16 @@ declare namespace stateKeys {
11392
11406
  return legacyServiceNested(serviceId, out);
11393
11407
  }
11394
11408
 
11395
- return serviceNested(serviceId, tryAsU32(2 ** 32 - 2), hash);
11409
+ return serviceNested(blake2b, serviceId, tryAsU32(2 ** 32 - 2), hash);
11396
11410
  }
11397
11411
 
11398
11412
  /** https://graypaper.fluffylabs.dev/#/1c979cb/3b0a043b0a04?v=0.7.1 */
11399
- export function serviceLookupHistory(serviceId: ServiceId, hash: PreimageHash, preimageLength: U32): StateKey {
11413
+ export function serviceLookupHistory(
11414
+ blake2b: Blake2b,
11415
+ serviceId: ServiceId,
11416
+ hash: PreimageHash,
11417
+ preimageLength: U32,
11418
+ ): StateKey {
11400
11419
  if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
11401
11420
  const doubleHash = blake2b.hashBytes(hash);
11402
11421
  const out = Bytes.zero(HASH_SIZE);
@@ -11405,11 +11424,11 @@ declare namespace stateKeys {
11405
11424
  return legacyServiceNested(serviceId, out);
11406
11425
  }
11407
11426
 
11408
- return serviceNested(serviceId, preimageLength, hash);
11427
+ return serviceNested(blake2b, serviceId, preimageLength, hash);
11409
11428
  }
11410
11429
 
11411
11430
  /** https://graypaper.fluffylabs.dev/#/1c979cb/3b88003b8800?v=0.7.1 */
11412
- export function serviceNested(serviceId: ServiceId, numberPrefix: U32, hash: BytesBlob): StateKey {
11431
+ export function serviceNested(blake2b: Blake2b, serviceId: ServiceId, numberPrefix: U32, hash: BytesBlob): StateKey {
11413
11432
  const inputToHash = BytesBlob.blobFromParts(u32AsLeBytes(numberPrefix), hash.raw);
11414
11433
  const newHash = blake2b.hashBytes(inputToHash).raw.subarray(0, 28);
11415
11434
  const key = Bytes.zero(HASH_SIZE);
@@ -11589,24 +11608,26 @@ declare namespace serialize {
11589
11608
  /** C(255, s): https://graypaper.fluffylabs.dev/#/85129da/383103383103?v=0.6.3 */
11590
11609
  export const serviceData = (serviceId: ServiceId) => ({
11591
11610
  key: stateKeys.serviceInfo(serviceId),
11592
- Codec: ServiceAccountInfo.Codec,
11611
+ Codec: Compatibility.isGreaterOrEqual(GpVersion.V0_7_1)
11612
+ ? codecWithVersion(ServiceAccountInfo.Codec)
11613
+ : ServiceAccountInfo.Codec,
11593
11614
  });
11594
11615
 
11595
11616
  /** https://graypaper.fluffylabs.dev/#/85129da/384803384803?v=0.6.3 */
11596
- export const serviceStorage = (serviceId: ServiceId, key: StorageKey) => ({
11597
- key: stateKeys.serviceStorage(serviceId, key),
11617
+ export const serviceStorage = (blake2b: Blake2b, serviceId: ServiceId, key: StorageKey) => ({
11618
+ key: stateKeys.serviceStorage(blake2b, serviceId, key),
11598
11619
  Codec: dumpCodec,
11599
11620
  });
11600
11621
 
11601
11622
  /** https://graypaper.fluffylabs.dev/#/85129da/385b03385b03?v=0.6.3 */
11602
- export const servicePreimages = (serviceId: ServiceId, hash: PreimageHash) => ({
11603
- key: stateKeys.servicePreimage(serviceId, hash),
11623
+ export const servicePreimages = (blake2b: Blake2b, serviceId: ServiceId, hash: PreimageHash) => ({
11624
+ key: stateKeys.servicePreimage(blake2b, serviceId, hash),
11604
11625
  Codec: dumpCodec,
11605
11626
  });
11606
11627
 
11607
11628
  /** https://graypaper.fluffylabs.dev/#/85129da/387603387603?v=0.6.3 */
11608
- export const serviceLookupHistory = (serviceId: ServiceId, hash: PreimageHash, len: U32) => ({
11609
- key: stateKeys.serviceLookupHistory(serviceId, hash, len),
11629
+ export const serviceLookupHistory = (blake2b: Blake2b, serviceId: ServiceId, hash: PreimageHash, len: U32) => ({
11630
+ key: stateKeys.serviceLookupHistory(blake2b, serviceId, hash, len),
11610
11631
  Codec: readonlyArray(codec.sequenceVarLen(codec.u32)),
11611
11632
  });
11612
11633
  }
@@ -11641,6 +11662,7 @@ declare const EMPTY_BLOB = BytesBlob.empty();
11641
11662
  /** Serialize given state update into a series of key-value pairs. */
11642
11663
  declare function* serializeStateUpdate(
11643
11664
  spec: ChainSpec,
11665
+ blake2b: Blake2b,
11644
11666
  update: Partial<State & ServicesUpdate>,
11645
11667
  ): Generator<StateEntryUpdate> {
11646
11668
  // first let's serialize all of the simple entries (if present!)
@@ -11649,9 +11671,9 @@ declare function* serializeStateUpdate(
11649
11671
  const encode = <T>(codec: Encode<T>, val: T) => Encoder.encodeObject(codec, val, spec);
11650
11672
 
11651
11673
  // then let's proceed with service updates
11652
- yield* serializeServiceUpdates(update.servicesUpdates, encode);
11653
- yield* serializePreimages(update.preimages, encode);
11654
- yield* serializeStorage(update.storage);
11674
+ yield* serializeServiceUpdates(update.servicesUpdates, encode, blake2b);
11675
+ yield* serializePreimages(update.preimages, encode, blake2b);
11676
+ yield* serializeStorage(update.storage, blake2b);
11655
11677
  yield* serializeRemovedServices(update.servicesRemoved);
11656
11678
  }
11657
11679
 
@@ -11663,18 +11685,18 @@ declare function* serializeRemovedServices(servicesRemoved: ServiceId[] | undefi
11663
11685
  }
11664
11686
  }
11665
11687
 
11666
- declare function* serializeStorage(storage: UpdateStorage[] | undefined): Generator<StateEntryUpdate> {
11688
+ declare function* serializeStorage(storage: UpdateStorage[] | undefined, blake2b: Blake2b): Generator<StateEntryUpdate> {
11667
11689
  for (const { action, serviceId } of storage ?? []) {
11668
11690
  switch (action.kind) {
11669
11691
  case UpdateStorageKind.Set: {
11670
11692
  const key = action.storage.key;
11671
- const codec = serialize.serviceStorage(serviceId, key);
11693
+ const codec = serialize.serviceStorage(blake2b, serviceId, key);
11672
11694
  yield [StateEntryUpdateAction.Insert, codec.key, action.storage.value];
11673
11695
  break;
11674
11696
  }
11675
11697
  case UpdateStorageKind.Remove: {
11676
11698
  const key = action.key;
11677
- const codec = serialize.serviceStorage(serviceId, key);
11699
+ const codec = serialize.serviceStorage(blake2b, serviceId, key);
11678
11700
  yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
11679
11701
  break;
11680
11702
  }
@@ -11684,16 +11706,20 @@ declare function* serializeStorage(storage: UpdateStorage[] | undefined): Genera
11684
11706
  }
11685
11707
  }
11686
11708
 
11687
- declare function* serializePreimages(preimages: UpdatePreimage[] | undefined, encode: EncodeFun): Generator<StateEntryUpdate> {
11709
+ declare function* serializePreimages(
11710
+ preimages: UpdatePreimage[] | undefined,
11711
+ encode: EncodeFun,
11712
+ blake2b: Blake2b,
11713
+ ): Generator<StateEntryUpdate> {
11688
11714
  for (const { action, serviceId } of preimages ?? []) {
11689
11715
  switch (action.kind) {
11690
11716
  case UpdatePreimageKind.Provide: {
11691
11717
  const { hash, blob } = action.preimage;
11692
- const codec = serialize.servicePreimages(serviceId, hash);
11718
+ const codec = serialize.servicePreimages(blake2b, serviceId, hash);
11693
11719
  yield [StateEntryUpdateAction.Insert, codec.key, blob];
11694
11720
 
11695
11721
  if (action.slot !== null) {
11696
- const codec2 = serialize.serviceLookupHistory(serviceId, hash, tryAsU32(blob.length));
11722
+ const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, tryAsU32(blob.length));
11697
11723
  yield [
11698
11724
  StateEntryUpdateAction.Insert,
11699
11725
  codec2.key,
@@ -11704,16 +11730,16 @@ declare function* serializePreimages(preimages: UpdatePreimage[] | undefined, en
11704
11730
  }
11705
11731
  case UpdatePreimageKind.UpdateOrAdd: {
11706
11732
  const { hash, length, slots } = action.item;
11707
- const codec = serialize.serviceLookupHistory(serviceId, hash, length);
11733
+ const codec = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
11708
11734
  yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, slots)];
11709
11735
  break;
11710
11736
  }
11711
11737
  case UpdatePreimageKind.Remove: {
11712
11738
  const { hash, length } = action;
11713
- const codec = serialize.servicePreimages(serviceId, hash);
11739
+ const codec = serialize.servicePreimages(blake2b, serviceId, hash);
11714
11740
  yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
11715
11741
 
11716
- const codec2 = serialize.serviceLookupHistory(serviceId, hash, length);
11742
+ const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
11717
11743
  yield [StateEntryUpdateAction.Remove, codec2.key, EMPTY_BLOB];
11718
11744
  break;
11719
11745
  }
@@ -11725,6 +11751,7 @@ declare function* serializePreimages(preimages: UpdatePreimage[] | undefined, en
11725
11751
  declare function* serializeServiceUpdates(
11726
11752
  servicesUpdates: UpdateService[] | undefined,
11727
11753
  encode: EncodeFun,
11754
+ blake2b: Blake2b,
11728
11755
  ): Generator<StateEntryUpdate> {
11729
11756
  for (const { action, serviceId } of servicesUpdates ?? []) {
11730
11757
  // new service being created or updated
@@ -11734,7 +11761,7 @@ declare function* serializeServiceUpdates(
11734
11761
  // additional lookup history update
11735
11762
  if (action.kind === UpdateServiceKind.Create && action.lookupHistory !== null) {
11736
11763
  const { lookupHistory } = action;
11737
- const codec2 = serialize.serviceLookupHistory(serviceId, lookupHistory.hash, lookupHistory.length);
11764
+ const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, lookupHistory.hash, lookupHistory.length);
11738
11765
  yield [StateEntryUpdateAction.Insert, codec2.key, encode(codec2.Codec, lookupHistory.slots)];
11739
11766
  }
11740
11767
  }
@@ -11868,8 +11895,8 @@ declare class StateEntries {
11868
11895
  );
11869
11896
 
11870
11897
  /** Turn in-memory state into it's serialized form. */
11871
- static serializeInMemory(spec: ChainSpec, state: InMemoryState) {
11872
- return new StateEntries(convertInMemoryStateToDictionary(spec, state));
11898
+ static serializeInMemory(spec: ChainSpec, blake2b: Blake2b, state: InMemoryState) {
11899
+ return new StateEntries(convertInMemoryStateToDictionary(spec, blake2b, state));
11873
11900
  }
11874
11901
 
11875
11902
  /**
@@ -11924,7 +11951,8 @@ declare class StateEntries {
11924
11951
  }
11925
11952
 
11926
11953
  /** https://graypaper.fluffylabs.dev/#/68eaa1f/391600391600?v=0.6.4 */
11927
- getRootHash(): StateRootHash {
11954
+ getRootHash(blake2b: Blake2b): StateRootHash {
11955
+ const blake2bTrieHasher = getBlake2bTrieHasher(blake2b);
11928
11956
  const leaves: SortedSet<LeafNode> = SortedSet.fromArray(leafComparator);
11929
11957
  for (const [key, value] of this) {
11930
11958
  leaves.insert(InMemoryTrie.constructLeaf(blake2bTrieHasher, key.asOpaque(), value));
@@ -11937,6 +11965,7 @@ declare class StateEntries {
11937
11965
  /** https://graypaper.fluffylabs.dev/#/68eaa1f/38a50038a500?v=0.6.4 */
11938
11966
  declare function convertInMemoryStateToDictionary(
11939
11967
  spec: ChainSpec,
11968
+ blake2b: Blake2b,
11940
11969
  state: InMemoryState,
11941
11970
  ): TruncatedHashDictionary<StateKey, BytesBlob> {
11942
11971
  const serialized = TruncatedHashDictionary.fromEntries<StateKey, BytesBlob>([]);
@@ -11969,20 +11998,25 @@ declare function convertInMemoryStateToDictionary(
11969
11998
 
11970
11999
  // preimages
11971
12000
  for (const preimage of service.data.preimages.values()) {
11972
- const { key, Codec } = serialize.servicePreimages(serviceId, preimage.hash);
12001
+ const { key, Codec } = serialize.servicePreimages(blake2b, serviceId, preimage.hash);
11973
12002
  serialized.set(key, Encoder.encodeObject(Codec, preimage.blob));
11974
12003
  }
11975
12004
 
11976
12005
  // storage
11977
12006
  for (const storage of service.data.storage.values()) {
11978
- const { key, Codec } = serialize.serviceStorage(serviceId, storage.key);
12007
+ const { key, Codec } = serialize.serviceStorage(blake2b, serviceId, storage.key);
11979
12008
  serialized.set(key, Encoder.encodeObject(Codec, storage.value));
11980
12009
  }
11981
12010
 
11982
12011
  // lookup history
11983
12012
  for (const lookupHistoryList of service.data.lookupHistory.values()) {
11984
12013
  for (const lookupHistory of lookupHistoryList) {
11985
- const { key, Codec } = serialize.serviceLookupHistory(serviceId, lookupHistory.hash, lookupHistory.length);
12014
+ const { key, Codec } = serialize.serviceLookupHistory(
12015
+ blake2b,
12016
+ serviceId,
12017
+ lookupHistory.hash,
12018
+ lookupHistory.length,
12019
+ );
11986
12020
  serialized.set(key, Encoder.encodeObject(Codec, lookupHistory.slots.slice()));
11987
12021
  }
11988
12022
  }
@@ -12013,21 +12047,23 @@ declare class SerializedState<T extends SerializedStateBackend = SerializedState
12013
12047
  implements State, EnumerableState
12014
12048
  {
12015
12049
  /** Create a state-like object from collection of serialized entries. */
12016
- static fromStateEntries(spec: ChainSpec, state: StateEntries, recentServices: ServiceId[] = []) {
12017
- return new SerializedState(spec, state, recentServices);
12050
+ static fromStateEntries(spec: ChainSpec, blake2b: Blake2b, state: StateEntries, recentServices: ServiceId[] = []) {
12051
+ return new SerializedState(spec, blake2b, state, recentServices);
12018
12052
  }
12019
12053
 
12020
12054
  /** Create a state-like object backed by some DB. */
12021
12055
  static new<T extends SerializedStateBackend>(
12022
12056
  spec: ChainSpec,
12057
+ blake2b: Blake2b,
12023
12058
  db: T,
12024
12059
  recentServices: ServiceId[] = [],
12025
12060
  ): SerializedState<T> {
12026
- return new SerializedState(spec, db, recentServices);
12061
+ return new SerializedState(spec, blake2b, db, recentServices);
12027
12062
  }
12028
12063
 
12029
12064
  private constructor(
12030
12065
  private readonly spec: ChainSpec,
12066
+ private readonly blake2b: Blake2b,
12031
12067
  public backend: T,
12032
12068
  /** Best-effort list of recently active services. */
12033
12069
  private readonly _recentServiceIds: ServiceId[],
@@ -12058,7 +12094,7 @@ declare class SerializedState<T extends SerializedStateBackend = SerializedState
12058
12094
  this._recentServiceIds.push(id);
12059
12095
  }
12060
12096
 
12061
- return new SerializedService(id, serviceData, (key) => this.retrieveOptional(key));
12097
+ return new SerializedService(this.blake2b, id, serviceData, (key) => this.retrieveOptional(key));
12062
12098
  }
12063
12099
 
12064
12100
  private retrieve<T>({ key, Codec }: KeyAndCodec<T>, description: string): T {
@@ -12157,6 +12193,7 @@ declare class SerializedState<T extends SerializedStateBackend = SerializedState
12157
12193
  /** Service data representation on a serialized state. */
12158
12194
  declare class SerializedService implements Service {
12159
12195
  constructor(
12196
+ public readonly blake2b: Blake2b,
12160
12197
  /** Service id */
12161
12198
  public readonly serviceId: ServiceId,
12162
12199
  private readonly accountInfo: ServiceAccountInfo,
@@ -12172,14 +12209,14 @@ declare class SerializedService implements Service {
12172
12209
  getStorage(rawKey: StorageKey): BytesBlob | null {
12173
12210
  if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
12174
12211
  const SERVICE_ID_BYTES = 4;
12175
- const serviceIdAndKey = new Uint8Array(SERVICE_ID_BYTES + rawKey.length);
12212
+ const serviceIdAndKey = safeAllocUint8Array(SERVICE_ID_BYTES + rawKey.length);
12176
12213
  serviceIdAndKey.set(u32AsLeBytes(this.serviceId));
12177
12214
  serviceIdAndKey.set(rawKey.raw, SERVICE_ID_BYTES);
12178
- const key: StorageKey = asOpaqueType(BytesBlob.blobFrom(blake2b.hashBytes(serviceIdAndKey).raw));
12179
- return this.retrieveOptional(serialize.serviceStorage(this.serviceId, key)) ?? null;
12215
+ const key: StorageKey = asOpaqueType(BytesBlob.blobFrom(this.blake2b.hashBytes(serviceIdAndKey).raw));
12216
+ return this.retrieveOptional(serialize.serviceStorage(this.blake2b, this.serviceId, key)) ?? null;
12180
12217
  }
12181
12218
 
12182
- return this.retrieveOptional(serialize.serviceStorage(this.serviceId, rawKey)) ?? null;
12219
+ return this.retrieveOptional(serialize.serviceStorage(this.blake2b, this.serviceId, rawKey)) ?? null;
12183
12220
  }
12184
12221
 
12185
12222
  /**
@@ -12189,17 +12226,17 @@ declare class SerializedService implements Service {
12189
12226
  */
12190
12227
  hasPreimage(hash: PreimageHash): boolean {
12191
12228
  // TODO [ToDr] consider optimizing to avoid fetching the whole data.
12192
- return this.retrieveOptional(serialize.servicePreimages(this.serviceId, hash)) !== undefined;
12229
+ return this.retrieveOptional(serialize.servicePreimages(this.blake2b, this.serviceId, hash)) !== undefined;
12193
12230
  }
12194
12231
 
12195
12232
  /** Retrieve preimage from the DB. */
12196
12233
  getPreimage(hash: PreimageHash): BytesBlob | null {
12197
- return this.retrieveOptional(serialize.servicePreimages(this.serviceId, hash)) ?? null;
12234
+ return this.retrieveOptional(serialize.servicePreimages(this.blake2b, this.serviceId, hash)) ?? null;
12198
12235
  }
12199
12236
 
12200
12237
  /** Retrieve preimage lookup history. */
12201
12238
  getLookupHistory(hash: PreimageHash, len: U32): LookupHistorySlots | null {
12202
- const rawSlots = this.retrieveOptional(serialize.serviceLookupHistory(this.serviceId, hash, len));
12239
+ const rawSlots = this.retrieveOptional(serialize.serviceLookupHistory(this.blake2b, this.serviceId, hash, len));
12203
12240
  if (rawSlots === undefined) {
12204
12241
  return null;
12205
12242
  }
@@ -12212,9 +12249,9 @@ type KeyAndCodec<T> = {
12212
12249
  Codec: Decode<T>;
12213
12250
  };
12214
12251
 
12215
- declare function loadState(spec: ChainSpec, entries: Iterable<[StateKey | TruncatedHash, BytesBlob]>) {
12252
+ declare function loadState(spec: ChainSpec, blake2b: Blake2b, entries: Iterable<[StateKey | TruncatedHash, BytesBlob]>) {
12216
12253
  const stateEntries = StateEntries.fromEntriesUnsafe(entries);
12217
- return SerializedState.fromStateEntries(spec, stateEntries);
12254
+ return SerializedState.fromStateEntries(spec, blake2b, stateEntries);
12218
12255
  }
12219
12256
 
12220
12257
  /**
@@ -12370,7 +12407,8 @@ declare class LeafDb implements SerializedStateBackend {
12370
12407
  assertNever(val);
12371
12408
  }
12372
12409
 
12373
- getStateRoot(): StateRootHash {
12410
+ getStateRoot(blake2b: Blake2b): StateRootHash {
12411
+ const blake2bTrieHasher = getBlake2bTrieHasher(blake2b);
12374
12412
  return InMemoryTrie.computeStateRoot(blake2bTrieHasher, this.leaves).asOpaque();
12375
12413
  }
12376
12414
 
@@ -12468,7 +12506,8 @@ declare class InMemoryStates implements StatesDb<InMemoryState> {
12468
12506
  }
12469
12507
 
12470
12508
  async getStateRoot(state: InMemoryState): Promise<StateRootHash> {
12471
- return StateEntries.serializeInMemory(this.spec, state).getRootHash();
12509
+ const blake2b = await Blake2b.createHasher();
12510
+ return StateEntries.serializeInMemory(this.spec, blake2b, state).getRootHash(blake2b);
12472
12511
  }
12473
12512
 
12474
12513
  /** Insert a full state into the database. */
@@ -12573,7 +12612,7 @@ declare function padAndEncodeData(input: BytesBlob) {
12573
12612
  const paddedLength = Math.ceil(input.length / PIECE_SIZE) * PIECE_SIZE;
12574
12613
  let padded = input;
12575
12614
  if (input.length !== paddedLength) {
12576
- padded = BytesBlob.blobFrom(new Uint8Array(paddedLength));
12615
+ padded = BytesBlob.blobFrom(safeAllocUint8Array(paddedLength));
12577
12616
  padded.raw.set(input.raw, 0);
12578
12617
  }
12579
12618
  return chunkingFunction(padded);
@@ -12629,7 +12668,7 @@ declare function decodeData(input: FixedSizeArray<[number, BytesBlob], N_CHUNKS_
12629
12668
  */
12630
12669
  declare function encodePoints(input: Bytes<PIECE_SIZE>): FixedSizeArray<Bytes<POINT_LENGTH>, N_CHUNKS_TOTAL> {
12631
12670
  const result: Bytes<POINT_LENGTH>[] = [];
12632
- const data = new Uint8Array(POINT_ALIGNMENT * N_CHUNKS_REQUIRED);
12671
+ const data = safeAllocUint8Array(POINT_ALIGNMENT * N_CHUNKS_REQUIRED);
12633
12672
 
12634
12673
  // add original shards to the result
12635
12674
  for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
@@ -12649,7 +12688,7 @@ declare function encodePoints(input: Bytes<PIECE_SIZE>): FixedSizeArray<Bytes<PO
12649
12688
  for (let i = 0; i < N_CHUNKS_REDUNDANCY; i++) {
12650
12689
  const pointIndex = i * POINT_ALIGNMENT;
12651
12690
 
12652
- const redundancyPoint = new Uint8Array(POINT_LENGTH);
12691
+ const redundancyPoint = safeAllocUint8Array(POINT_LENGTH);
12653
12692
  for (let j = 0; j < POINT_LENGTH; j++) {
12654
12693
  redundancyPoint[j] = encodedData[pointIndex + j * HALF_POINT_SIZE];
12655
12694
  }
@@ -12669,7 +12708,7 @@ declare function decodePiece(
12669
12708
  ): Bytes<PIECE_SIZE> {
12670
12709
  const result = Bytes.zero(PIECE_SIZE);
12671
12710
 
12672
- const data = new Uint8Array(N_CHUNKS_REQUIRED * POINT_ALIGNMENT);
12711
+ const data = safeAllocUint8Array(N_CHUNKS_REQUIRED * POINT_ALIGNMENT);
12673
12712
  const indices = new Uint16Array(input.length);
12674
12713
 
12675
12714
  for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
@@ -12796,7 +12835,7 @@ declare function lace<N extends number, K extends number>(input: FixedSizeArray<
12796
12835
  return BytesBlob.empty();
12797
12836
  }
12798
12837
  const n = input[0].length;
12799
- const result = BytesBlob.blobFrom(new Uint8Array(k * n));
12838
+ const result = BytesBlob.blobFrom(safeAllocUint8Array(k * n));
12800
12839
  for (let i = 0; i < k; i++) {
12801
12840
  const entry = input[i].raw;
12802
12841
  for (let j = 0; j < n; j++) {
@@ -13694,13 +13733,12 @@ interface PartialState {
13694
13733
 
13695
13734
  /**
13696
13735
  * Transfer given `amount` of funds to the `destination`,
13697
- * passing `suppliedGas` to invoke `OnTransfer` entry point
13698
- * and given `memo`.
13736
+ * passing `gas` fee for transfer and given `memo`.
13699
13737
  */
13700
13738
  transfer(
13701
13739
  destination: ServiceId | null,
13702
13740
  amount: U64,
13703
- suppliedGas: ServiceGas,
13741
+ gas: ServiceGas,
13704
13742
  memo: Bytes<TRANSFER_MEMO_BYTES>,
13705
13743
  ): Result$2<OK, TransferError>;
13706
13744
 
@@ -13869,7 +13907,7 @@ declare class Mask {
13869
13907
  }
13870
13908
 
13871
13909
  private buildLookupTableForward(mask: BitVec) {
13872
- const table = new Uint8Array(mask.bitLength);
13910
+ const table = safeAllocUint8Array(mask.bitLength);
13873
13911
  let lastInstructionOffset = 0;
13874
13912
  for (let i = mask.bitLength - 1; i >= 0; i--) {
13875
13913
  if (mask.isSet(i)) {
@@ -14013,7 +14051,7 @@ declare class Registers {
14013
14051
  private asSigned: BigInt64Array;
14014
14052
  private asUnsigned: BigUint64Array;
14015
14053
 
14016
- constructor(private readonly bytes = new Uint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
14054
+ constructor(private readonly bytes = safeAllocUint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
14017
14055
  check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
14018
14056
  this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
14019
14057
  this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
@@ -18071,9 +18109,15 @@ type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
18071
18109
  /** Attempt to convert a number into `HostCallIndex`. */
18072
18110
  declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
18073
18111
 
18112
+ /**
18113
+ * Host-call exit reason.
18114
+ *
18115
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
18116
+ */
18074
18117
  declare enum PvmExecution {
18075
18118
  Halt = 0,
18076
18119
  Panic = 1,
18120
+ OOG = 2, // out-of-gas
18077
18121
  }
18078
18122
 
18079
18123
  /** A utility function to easily trace a bunch of registers. */
@@ -18086,8 +18130,12 @@ interface HostCallHandler {
18086
18130
  /** Index of that host call (i.e. what PVM invokes via `ecalli`) */
18087
18131
  readonly index: HostCallIndex;
18088
18132
 
18089
- /** The gas cost of invocation of that host call. */
18090
- readonly gasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
18133
+ /**
18134
+ * The gas cost of invocation of that host call.
18135
+ *
18136
+ * NOTE: `((reg: IHostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
18137
+ */
18138
+ readonly basicGasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
18091
18139
 
18092
18140
  /** Currently executing service id. */
18093
18141
  readonly currentServiceId: U32;
@@ -18230,7 +18278,7 @@ declare class HostCalls {
18230
18278
  const maybeAddress = regs.getLowerU32(7);
18231
18279
  const maybeLength = regs.getLowerU32(8);
18232
18280
 
18233
- const result = new Uint8Array(maybeLength);
18281
+ const result = safeAllocUint8Array(maybeLength);
18234
18282
  const startAddress = tryAsMemoryIndex(maybeAddress);
18235
18283
  const loadResult = memory.loadInto(result, startAddress);
18236
18284
 
@@ -18263,8 +18311,10 @@ declare class HostCalls {
18263
18311
 
18264
18312
  const hostCall = this.hostCalls.get(index);
18265
18313
  const gasBefore = gas.get();
18266
- const gasCost = typeof hostCall.gasCost === "number" ? hostCall.gasCost : hostCall.gasCost(regs);
18267
- const underflow = gas.sub(gasCost);
18314
+ // NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
18315
+ const basicGasCost =
18316
+ typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
18317
+ const underflow = gas.sub(basicGasCost);
18268
18318
 
18269
18319
  const pcLog = `[PC: ${pvmInstance.getPC()}]`;
18270
18320
  if (underflow) {
@@ -18291,6 +18341,11 @@ declare class HostCalls {
18291
18341
  return this.getReturnValue(status, pvmInstance);
18292
18342
  }
18293
18343
 
18344
+ if (result === PvmExecution.OOG) {
18345
+ status = Status.OOG;
18346
+ return this.getReturnValue(status, pvmInstance);
18347
+ }
18348
+
18294
18349
  if (result === undefined) {
18295
18350
  pvmInstance.runProgram();
18296
18351
  status = pvmInstance.getStatus();
@@ -18662,7 +18717,7 @@ declare class DebuggerAdapter {
18662
18717
 
18663
18718
  if (page === null) {
18664
18719
  // page wasn't allocated so we return an empty page
18665
- return new Uint8Array(PAGE_SIZE);
18720
+ return safeAllocUint8Array(PAGE_SIZE);
18666
18721
  }
18667
18722
 
18668
18723
  if (page.length === PAGE_SIZE) {
@@ -18671,7 +18726,7 @@ declare class DebuggerAdapter {
18671
18726
  }
18672
18727
 
18673
18728
  // page was allocated but it is shorter than PAGE_SIZE so we have to extend it
18674
- const fullPage = new Uint8Array(PAGE_SIZE);
18729
+ const fullPage = safeAllocUint8Array(PAGE_SIZE);
18675
18730
  fullPage.set(page);
18676
18731
  return fullPage;
18677
18732
  }
@@ -18864,10 +18919,10 @@ type ENTROPY_BYTES = typeof ENTROPY_BYTES;
18864
18919
  *
18865
18920
  * https://graypaper.fluffylabs.dev/#/579bd12/3b9a013b9a01
18866
18921
  */
18867
- declare function fisherYatesShuffle<T>(arr: T[], entropy: Bytes<ENTROPY_BYTES>): T[] {
18922
+ declare function fisherYatesShuffle<T>(blake2b: Blake2b, arr: T[], entropy: Bytes<ENTROPY_BYTES>): T[] {
18868
18923
  check`${entropy.length === ENTROPY_BYTES} Expected entropy of length ${ENTROPY_BYTES}, got ${entropy.length}`;
18869
18924
  const n = arr.length;
18870
- const randomNumbers = hashToNumberSequence(entropy, arr.length);
18925
+ const randomNumbers = hashToNumberSequence(blake2b, entropy, arr.length);
18871
18926
  const result: T[] = new Array<T>(n);
18872
18927
 
18873
18928
  let itemsLeft = n;
@@ -19039,8 +19094,7 @@ declare const availabilityAssignmentFromJson = json.object<JsonAvailabilityAssig
19039
19094
  timeout: "number",
19040
19095
  },
19041
19096
  ({ report, timeout }) => {
19042
- const workReportHash = blake2b.hashBytes(Encoder.encodeObject(WorkReport.Codec, report)).asOpaque();
19043
- return AvailabilityAssignment.create({ workReport: new WithHash(workReportHash, report), timeout });
19097
+ return AvailabilityAssignment.create({ workReport: report, timeout });
19044
19098
  },
19045
19099
  );
19046
19100
 
@@ -19541,7 +19595,7 @@ declare class TransitionHasher implements MmrHasher<KeccakHash> {
19541
19595
  constructor(
19542
19596
  private readonly context: ChainSpec,
19543
19597
  private readonly keccakHasher: KeccakHasher,
19544
- private readonly allocator: HashAllocator,
19598
+ public readonly blake2b: Blake2b,
19545
19599
  ) {}
19546
19600
 
19547
19601
  /** Concatenates two hashes and hash this concatenation */
@@ -19555,7 +19609,7 @@ declare class TransitionHasher implements MmrHasher<KeccakHash> {
19555
19609
 
19556
19610
  /** Creates hash from the block header view */
19557
19611
  header(header: HeaderView): WithHash<HeaderHash, HeaderView> {
19558
- return new WithHash(blake2b.hashBytes(header.encoded(), this.allocator).asOpaque(), header);
19612
+ return new WithHash(this.blake2b.hashBytes(header.encoded()).asOpaque(), header);
19559
19613
  }
19560
19614
 
19561
19615
  /**
@@ -19569,7 +19623,7 @@ declare class TransitionHasher implements MmrHasher<KeccakHash> {
19569
19623
  .view()
19570
19624
  .map((g) => g.view())
19571
19625
  .map((guarantee) => {
19572
- const reportHash = blake2b.hashBytes(guarantee.report.encoded(), this.allocator).asOpaque<WorkReportHash>();
19626
+ const reportHash = this.blake2b.hashBytes(guarantee.report.encoded()).asOpaque<WorkReportHash>();
19573
19627
  return BytesBlob.blobFromParts([
19574
19628
  reportHash.raw,
19575
19629
  guarantee.slot.encoded().raw,
@@ -19579,15 +19633,15 @@ declare class TransitionHasher implements MmrHasher<KeccakHash> {
19579
19633
 
19580
19634
  const guaranteeBlob = Encoder.encodeObject(codec.sequenceVarLen(dumpCodec), guarantees, this.context);
19581
19635
 
19582
- const et = blake2b.hashBytes(extrinsicView.tickets.encoded(), this.allocator).asOpaque<ExtrinsicHash>();
19583
- const ep = blake2b.hashBytes(extrinsicView.preimages.encoded(), this.allocator).asOpaque<ExtrinsicHash>();
19584
- const eg = blake2b.hashBytes(guaranteeBlob, this.allocator).asOpaque<ExtrinsicHash>();
19585
- const ea = blake2b.hashBytes(extrinsicView.assurances.encoded(), this.allocator).asOpaque<ExtrinsicHash>();
19586
- const ed = blake2b.hashBytes(extrinsicView.disputes.encoded(), this.allocator).asOpaque<ExtrinsicHash>();
19636
+ const et = this.blake2b.hashBytes(extrinsicView.tickets.encoded()).asOpaque<ExtrinsicHash>();
19637
+ const ep = this.blake2b.hashBytes(extrinsicView.preimages.encoded()).asOpaque<ExtrinsicHash>();
19638
+ const eg = this.blake2b.hashBytes(guaranteeBlob).asOpaque<ExtrinsicHash>();
19639
+ const ea = this.blake2b.hashBytes(extrinsicView.assurances.encoded()).asOpaque<ExtrinsicHash>();
19640
+ const ed = this.blake2b.hashBytes(extrinsicView.disputes.encoded()).asOpaque<ExtrinsicHash>();
19587
19641
 
19588
19642
  const encoded = BytesBlob.blobFromParts([et.raw, ep.raw, eg.raw, ea.raw, ed.raw]);
19589
19643
 
19590
- return new WithHashAndBytes(blake2b.hashBytes(encoded, this.allocator).asOpaque(), extrinsicView, encoded);
19644
+ return new WithHashAndBytes(this.blake2b.hashBytes(encoded).asOpaque(), extrinsicView, encoded);
19591
19645
  }
19592
19646
 
19593
19647
  /** Creates hash for given WorkPackage */
@@ -19598,7 +19652,7 @@ declare class TransitionHasher implements MmrHasher<KeccakHash> {
19598
19652
  private encode<T, THash extends OpaqueHash>(codec: Codec<T>, data: T): WithHashAndBytes<THash, T> {
19599
19653
  // TODO [ToDr] Use already allocated encoding destination and hash bytes from some arena.
19600
19654
  const encoded = Encoder.encodeObject(codec, data, this.context);
19601
- return new WithHashAndBytes(blake2b.hashBytes(encoded, this.allocator).asOpaque(), data, encoded);
19655
+ return new WithHashAndBytes(this.blake2b.hashBytes(encoded).asOpaque(), data, encoded);
19602
19656
  }
19603
19657
  }
19604
19658
 
@@ -19619,7 +19673,10 @@ declare enum PreimagesErrorCode {
19619
19673
 
19620
19674
  // TODO [SeKo] consider whether this module is the right place to remove expired preimages
19621
19675
  declare class Preimages {
19622
- constructor(public readonly state: PreimagesState) {}
19676
+ constructor(
19677
+ public readonly state: PreimagesState,
19678
+ public readonly blake2b: Blake2b,
19679
+ ) {}
19623
19680
 
19624
19681
  integrate(input: PreimagesInput): Result$2<PreimagesStateUpdate, PreimagesErrorCode> {
19625
19682
  // make sure lookup extrinsics are sorted and unique
@@ -19648,7 +19705,7 @@ declare class Preimages {
19648
19705
  // select preimages for integration
19649
19706
  for (const preimage of preimages) {
19650
19707
  const { requester, blob } = preimage;
19651
- const hash: PreimageHash = blake2b.hashBytes(blob).asOpaque();
19708
+ const hash: PreimageHash = this.blake2b.hashBytes(blob).asOpaque();
19652
19709
 
19653
19710
  const service = this.state.getService(requester);
19654
19711
  if (service === null) {
@@ -19679,156 +19736,6 @@ declare class Preimages {
19679
19736
  }
19680
19737
  }
19681
19738
 
19682
- declare enum ServiceExecutorError {
19683
- NoLookup = 0,
19684
- NoState = 1,
19685
- NoServiceCode = 2,
19686
- ServiceCodeMismatch = 3,
19687
- }
19688
-
19689
- declare class WorkPackageExecutor {
19690
- constructor(
19691
- private readonly blocks: BlocksDb,
19692
- private readonly state: StatesDb,
19693
- private readonly hasher: TransitionHasher,
19694
- ) {}
19695
-
19696
- // TODO [ToDr] this while thing should be triple-checked with the GP.
19697
- // I'm currently implementing some dirty version for the demo.
19698
- async executeWorkPackage(pack: WorkPackage): Promise<WorkReport> {
19699
- const headerHash = pack.context.lookupAnchor;
19700
- // execute authorisation first or is it already executed and we just need to check it?
19701
- const authExec = this.getServiceExecutor(
19702
- // TODO [ToDr] should this be anchor or lookupAnchor?
19703
- headerHash,
19704
- pack.authCodeHost,
19705
- pack.authCodeHash,
19706
- );
19707
-
19708
- if (authExec.isError) {
19709
- // TODO [ToDr] most likely shouldn't be throw.
19710
- throw new Error(`Could not get authorization executor: ${authExec.error}`);
19711
- }
19712
-
19713
- const pvm = authExec.ok;
19714
- const authGas = tryAsGas(15_000n);
19715
- const result = await pvm.run(pack.parametrization, authGas);
19716
-
19717
- if (!result.isEqualTo(pack.authorization)) {
19718
- throw new Error("Authorization is invalid.");
19719
- }
19720
-
19721
- const results: WorkResult[] = [];
19722
- for (const item of pack.items) {
19723
- const exec = this.getServiceExecutor(headerHash, item.service, item.codeHash);
19724
- if (exec.isError) {
19725
- throw new Error(`Could not get item executor: ${exec.error}`);
19726
- }
19727
- const pvm = exec.ok;
19728
-
19729
- const gasRatio = tryAsServiceGas(3_000n);
19730
- const ret = await pvm.run(item.payload, tryAsGas(item.refineGasLimit)); // or accumulateGasLimit?
19731
- results.push(
19732
- WorkResult.create({
19733
- serviceId: item.service,
19734
- codeHash: item.codeHash,
19735
- payloadHash: blake2b.hashBytes(item.payload),
19736
- gas: gasRatio,
19737
- result: new WorkExecResult(WorkExecResultKind.ok, ret),
19738
- load: WorkRefineLoad.create({
19739
- gasUsed: tryAsServiceGas(5),
19740
- importedSegments: tryAsU32(0),
19741
- exportedSegments: tryAsU32(0),
19742
- extrinsicSize: tryAsU32(0),
19743
- extrinsicCount: tryAsU32(0),
19744
- }),
19745
- }),
19746
- );
19747
- }
19748
-
19749
- const workPackage = this.hasher.workPackage(pack);
19750
- const workPackageSpec = WorkPackageSpec.create({
19751
- hash: workPackage.hash,
19752
- length: tryAsU32(workPackage.encoded.length),
19753
- erasureRoot: Bytes.zero(HASH_SIZE),
19754
- exportsRoot: Bytes.zero(HASH_SIZE).asOpaque(),
19755
- exportsCount: tryAsU16(0),
19756
- });
19757
- const coreIndex = tryAsCoreIndex(0);
19758
- const authorizerHash = Bytes.fill(HASH_SIZE, 5).asOpaque();
19759
-
19760
- const workResults = FixedSizeArray.new(results, tryAsWorkItemsCount(results.length));
19761
-
19762
- return Promise.resolve(
19763
- WorkReport.create({
19764
- workPackageSpec,
19765
- context: pack.context,
19766
- coreIndex,
19767
- authorizerHash,
19768
- authorizationOutput: pack.authorization,
19769
- segmentRootLookup: [],
19770
- results: workResults,
19771
- authorizationGasUsed: tryAsServiceGas(0),
19772
- }),
19773
- );
19774
- }
19775
-
19776
- getServiceExecutor(
19777
- lookupAnchor: HeaderHash,
19778
- serviceId: ServiceId,
19779
- expectedCodeHash: CodeHash,
19780
- ): Result$2<PvmExecutor, ServiceExecutorError> {
19781
- const header = this.blocks.getHeader(lookupAnchor);
19782
- if (header === null) {
19783
- return Result.error(ServiceExecutorError.NoLookup);
19784
- }
19785
-
19786
- const state = this.state.getState(lookupAnchor);
19787
- if (state === null) {
19788
- return Result.error(ServiceExecutorError.NoState);
19789
- }
19790
-
19791
- const service = state.getService(serviceId);
19792
- const serviceCodeHash = service?.getInfo().codeHash ?? null;
19793
- if (serviceCodeHash === null) {
19794
- return Result.error(ServiceExecutorError.NoServiceCode);
19795
- }
19796
-
19797
- if (!serviceCodeHash.isEqualTo(expectedCodeHash)) {
19798
- return Result.error(ServiceExecutorError.ServiceCodeMismatch);
19799
- }
19800
-
19801
- const serviceCode = service?.getPreimage(serviceCodeHash.asOpaque()) ?? null;
19802
- if (serviceCode === null) {
19803
- return Result.error(ServiceExecutorError.NoServiceCode);
19804
- }
19805
-
19806
- return Result.ok(new PvmExecutor(serviceCode));
19807
- }
19808
- }
19809
-
19810
- declare class PvmExecutor {
19811
- private readonly pvm: HostCalls;
19812
- private hostCalls = new HostCallsManager({ missing: new Missing() });
19813
- private pvmInstanceManager = new PvmInstanceManager(4);
19814
-
19815
- constructor(private serviceCode: BytesBlob) {
19816
- this.pvm = new PvmHostCallExtension(this.pvmInstanceManager, this.hostCalls);
19817
- }
19818
-
19819
- async run(args: BytesBlob, gas: Gas): Promise<BytesBlob> {
19820
- const program = Program.fromSpi(this.serviceCode.raw, args.raw, true);
19821
-
19822
- const result = await this.pvm.runProgram(program.code, 5, gas, program.registers, program.memory);
19823
-
19824
- if (result.hasMemorySlice()) {
19825
- return BytesBlob.blobFrom(result.memorySlice);
19826
- }
19827
-
19828
- return BytesBlob.empty();
19829
- }
19830
- }
19831
-
19832
19739
  type index_Preimages = Preimages;
19833
19740
  declare const index_Preimages: typeof Preimages;
19834
19741
  type index_PreimagesErrorCode = PreimagesErrorCode;
@@ -19838,10 +19745,8 @@ type index_PreimagesState = PreimagesState;
19838
19745
  type index_PreimagesStateUpdate = PreimagesStateUpdate;
19839
19746
  type index_TransitionHasher = TransitionHasher;
19840
19747
  declare const index_TransitionHasher: typeof TransitionHasher;
19841
- type index_WorkPackageExecutor = WorkPackageExecutor;
19842
- declare const index_WorkPackageExecutor: typeof WorkPackageExecutor;
19843
19748
  declare namespace index {
19844
- export { index_Preimages as Preimages, index_PreimagesErrorCode as PreimagesErrorCode, index_TransitionHasher as TransitionHasher, index_WorkPackageExecutor as WorkPackageExecutor };
19749
+ export { index_Preimages as Preimages, index_PreimagesErrorCode as PreimagesErrorCode, index_TransitionHasher as TransitionHasher };
19845
19750
  export type { index_PreimagesInput as PreimagesInput, index_PreimagesState as PreimagesState, index_PreimagesStateUpdate as PreimagesStateUpdate };
19846
19751
  }
19847
19752