@peerbit/trusted-network 6.0.107 → 6.0.109

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.
@@ -22,7 +22,9 @@ import {
22
22
  * resolver instead of being accumulated in memory.
23
23
  */
24
24
 
25
- const DEFAULT_MAX_PENDING_POLICIES_V2 = 64;
25
+ /** Internal protocol ceiling; this module is not part of the package root. */
26
+ export const TRUSTED_NETWORK_V2_MAX_PENDING_POLICIES = 64;
27
+ const DEFAULT_MAX_PENDING_POLICIES_V2 = TRUSTED_NETWORK_V2_MAX_PENDING_POLICIES;
26
28
  const PENDING_POLICY_ACCOUNTING_OVERHEAD_V2 = 64;
27
29
  const MAX_PENDING_POLICY_ACCOUNTED_BYTES_V2 =
28
30
  TRUSTED_NETWORK_V2_MAX_POLICY_ENTRY_BYTES * 2 +
@@ -33,7 +35,58 @@ const DEFAULT_POLICY_RESOLUTION_TIMEOUT_MS_V2 = 10 * 1000;
33
35
  const MAX_TIMER_DELAY_MS_V2 = 0x7fffffff;
34
36
  const MAX_UNAVAILABLE_REASON_LENGTH_V2 = 512;
35
37
 
36
- const copyBytes = (bytes: Uint8Array): Uint8Array => Uint8Array.from(bytes);
38
+ const TYPED_ARRAY_PROTOTYPE = Object.getPrototypeOf(Uint8Array.prototype);
39
+ const TYPED_ARRAY_BYTE_LENGTH = Object.getOwnPropertyDescriptor(
40
+ TYPED_ARRAY_PROTOTYPE,
41
+ "byteLength",
42
+ )!.get!;
43
+ const TYPED_ARRAY_TAG = Object.getOwnPropertyDescriptor(
44
+ TYPED_ARRAY_PROTOTYPE,
45
+ Symbol.toStringTag,
46
+ )!.get!;
47
+ const ARRAY_BUFFER_IS_VIEW = ArrayBuffer.isView;
48
+ const UINT8_ARRAY_SET = Uint8Array.prototype.set;
49
+
50
+ const exactUint8ArrayByteLength = (input: unknown): number => {
51
+ if (
52
+ !ARRAY_BUFFER_IS_VIEW(input) ||
53
+ TYPED_ARRAY_TAG.call(input) !== "Uint8Array"
54
+ ) {
55
+ throw new TypeError("Expected a genuine Uint8Array");
56
+ }
57
+ const byteLength = TYPED_ARRAY_BYTE_LENGTH.call(input) as number;
58
+ if (byteLength === 0) {
59
+ // The intrinsic getter reports zero for both empty and detached views. The
60
+ // intrinsic set distinguishes them without consulting caller properties.
61
+ UINT8_ARRAY_SET.call(new Uint8Array(0), input as Uint8Array);
62
+ }
63
+ return byteLength;
64
+ };
65
+
66
+ const copyBytesWithLength = (
67
+ bytes: Uint8Array,
68
+ byteLength: number,
69
+ ): Uint8Array => {
70
+ const copy = new Uint8Array(byteLength);
71
+ UINT8_ARRAY_SET.call(copy, bytes);
72
+ return copy;
73
+ };
74
+
75
+ const copyBytes = (bytes: Uint8Array): Uint8Array => {
76
+ const byteLength = exactUint8ArrayByteLength(bytes);
77
+ return copyBytesWithLength(bytes, byteLength);
78
+ };
79
+
80
+ const hasExactUint8ArrayByteLength = (
81
+ input: unknown,
82
+ expected: number,
83
+ ): input is Uint8Array => {
84
+ try {
85
+ return exactUint8ArrayByteLength(input) === expected;
86
+ } catch {
87
+ return false;
88
+ }
89
+ };
37
90
 
38
91
  const bytesKey = (bytes: Uint8Array): string => {
39
92
  let key = "";
@@ -227,13 +280,16 @@ class PolicyDependencyUnavailableErrorV2 extends Error {
227
280
  const capturePolicySnapshotEntryBytesV2 = (
228
281
  entryBytes: Uint8Array,
229
282
  ): Uint8Array => {
230
- if (!(entryBytes instanceof Uint8Array)) {
283
+ let byteLength: number;
284
+ try {
285
+ byteLength = exactUint8ArrayByteLength(entryBytes);
286
+ } catch {
231
287
  throw new Error("Policy snapshot must use canonical EntryV0 bytes");
232
288
  }
233
- if (entryBytes.byteLength === 0) {
289
+ if (byteLength === 0) {
234
290
  throw new Error("Policy snapshot must use EntryV0");
235
291
  }
236
- if (entryBytes.byteLength > TRUSTED_NETWORK_V2_MAX_POLICY_ENTRY_BYTES) {
292
+ if (byteLength > TRUSTED_NETWORK_V2_MAX_POLICY_ENTRY_BYTES) {
237
293
  throw new Error(
238
294
  `Policy snapshot entry must contain 1-${TRUSTED_NETWORK_V2_MAX_POLICY_ENTRY_BYTES} bytes`,
239
295
  );
@@ -241,7 +297,7 @@ const capturePolicySnapshotEntryBytesV2 = (
241
297
 
242
298
  // Apply the protocol byte ceiling before this first copy, decode, or crypto
243
299
  // operation. The retained copy also prevents caller mutation during awaits.
244
- return copyBytes(entryBytes);
300
+ return copyBytesWithLength(entryBytes, byteLength);
245
301
  };
246
302
 
247
303
  const authenticateCapturedPolicySnapshotEntryV2 = async (
@@ -292,12 +348,15 @@ const authenticateCapturedPolicySnapshotEntryV2 = async (
292
348
  }
293
349
 
294
350
  const payload = await authenticatedEntry.getPayloadValue();
295
- if (!(payload instanceof Uint8Array)) {
351
+ let canonicalPayload: Uint8Array;
352
+ try {
353
+ canonicalPayload = copyBytes(payload as Uint8Array);
354
+ } catch {
296
355
  throw new Error(
297
356
  "Policy snapshot payload must contain canonical body bytes",
298
357
  );
299
358
  }
300
- const body = decodePolicySnapshotBodyV2(copyBytes(payload), descriptor);
359
+ const body = decodePolicySnapshotBodyV2(canonicalPayload, descriptor);
301
360
  const digest = digestPolicySnapshotBodyV2(body);
302
361
  return {
303
362
  body: copyBody(body),
@@ -398,8 +457,7 @@ const captureDurableStateV2 = (
398
457
  };
399
458
  case "UNAVAILABLE": {
400
459
  if (
401
- !(durableState.acceptedAncestorDigest instanceof Uint8Array) ||
402
- durableState.acceptedAncestorDigest.byteLength !== 32
460
+ !hasExactUint8ArrayByteLength(durableState.acceptedAncestorDigest, 32)
403
461
  ) {
404
462
  throw new Error(
405
463
  "Unavailable accepted ancestor digest must contain exactly 32 bytes",
@@ -473,8 +531,14 @@ export class TrustedNetworkV2PolicyReducer {
473
531
  constructor(properties: TrustedNetworkV2PolicyReducerProperties) {
474
532
  assertNetworkDescriptorV2(properties.descriptor);
475
533
  const maxPending = properties.maxPending ?? DEFAULT_MAX_PENDING_POLICIES_V2;
476
- if (!Number.isSafeInteger(maxPending) || maxPending < 1) {
477
- throw new Error("maxPending must be a positive safe integer");
534
+ if (
535
+ !Number.isSafeInteger(maxPending) ||
536
+ maxPending < 1 ||
537
+ maxPending > TRUSTED_NETWORK_V2_MAX_PENDING_POLICIES
538
+ ) {
539
+ throw new Error(
540
+ `maxPending must be a positive safe integer no greater than ${TRUSTED_NETWORK_V2_MAX_PENDING_POLICIES}`,
541
+ );
478
542
  }
479
543
  const maxPendingPolicyBytes =
480
544
  properties.maxPendingPolicyBytes ?? DEFAULT_MAX_PENDING_POLICY_BYTES_V2;