trac-msb 0.2.20 → 0.2.21

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/SECURITY.md CHANGED
@@ -6,13 +6,11 @@ The following table shows which versions of this project are currently receiving
6
6
 
7
7
  | Version | Supported | Pear compatibility |
8
8
  | -------- | ------------------ | ------------------ |
9
- | 0.2.19 | :white_check_mark: | Pear v2 and v3 |
10
- | 0.2.18 | :white_check_mark: | Pear v2 only |
11
- | 0.2.17 | :white_check_mark: | Pear v2 only |
9
+ | 0.2.21 | :white_check_mark: | Pear v2 and v3 |
12
10
  | main | :warning: unstable | Pear v2 and v3 |
13
- | < 0.2.17 | :x: | N/A |
11
+ | < 0.2.21 | :x: | N/A |
14
12
 
15
- Versions older than 0.2.17 are deprecated.
13
+ Versions older than 0.2.21 are deprecated.
16
14
  Please upgrade to the latest release to ensure you receive security fixes.
17
15
 
18
16
  ---
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trac-msb",
3
3
  "main": "msb.mjs",
4
- "version": "0.2.20",
4
+ "version": "0.2.21",
5
5
  "pear": {
6
6
  "name": "trac-msb",
7
7
  "type": "terminal"
@@ -373,8 +373,8 @@ class ValidatorObserverService {
373
373
  * Rules:
374
374
  * - Skips invalid/malformed entries.
375
375
  * - Skips non-admin indexers.
376
- * - Deduplicates nodes by mapping their latest state to a unique address.
377
- * - Removes stale connections for nodes flagged with 'isRemoved'.
376
+ * - Deduplicates active writers by wallet address.
377
+ * - Removes stale connections only when no active writer remains for an address.
378
378
  * - Includes only valid and active writer nodes.
379
379
  * @param {Object} adminEntry - The current admin node entry.
380
380
  * @returns {Promise<Array<Object>>} A promise resolving to the deduplicated array of active writers.
@@ -385,13 +385,13 @@ class ValidatorObserverService {
385
385
  this.#keyDecodeCache.clear();
386
386
  }
387
387
 
388
- // Map is used for deduplication, ensuring that each node physical address
389
- // occupies only a single slot despite the append-only nature of Autobase
388
+ // Historical writer keys can share an address with an active replacement.
390
389
  const activeMap = new Map();
390
+ const removedMap = new Map();
391
391
 
392
392
  try {
393
393
  for await (const { key, value } of this.#state.base.system.list()) {
394
- if (!this.#shouldRun()) break;
394
+ if (!this.#shouldRun()) return Array.from(activeMap.values());
395
395
 
396
396
  if (!key || b4a.byteLength(key) !== WRITER_BYTE_LENGTH) continue;
397
397
  if (!value) continue;
@@ -426,16 +426,20 @@ class ValidatorObserverService {
426
426
 
427
427
  if (value.isIndexer && addr !== adminEntry?.address) continue;
428
428
 
429
- // Handles soft-delete: drops stale connections and removes the node from the pool
430
429
  if (value.isRemoved) {
431
- this.#enforceNoStaleConnections(publicKey);
432
- activeMap.delete(addr);
430
+ removedMap.set(addr, publicKey);
433
431
  continue;
434
432
  }
435
433
 
436
- // Registers or overwrites to maintain a single source of truth per machine
437
434
  activeMap.set(addr, { key, address: addr, publicKey, publicKeyHex });
438
435
  }
436
+
437
+ // Writer iteration order does not represent key age. Only a complete scan
438
+ // can establish that a removed writer has no active replacement.
439
+ for (const [addr, publicKey] of removedMap) {
440
+ if (!this.#shouldRun()) break;
441
+ if (!activeMap.has(addr)) this.#enforceNoStaleConnections(publicKey);
442
+ }
439
443
  } catch (err) {
440
444
  this.#logger.error(`Autobase writer scan error: ${err.message}`);
441
445
  }
@@ -462,4 +466,4 @@ class ValidatorObserverService {
462
466
  }
463
467
  }
464
468
 
465
- export default ValidatorObserverService;
469
+ export default ValidatorObserverService;