@optimystic/db-p2p 0.21.0 → 0.22.0

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 (83) hide show
  1. package/dist/src/cluster/cluster-policy.d.ts +13 -2
  2. package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
  3. package/dist/src/cluster/cluster-policy.js +51 -4
  4. package/dist/src/cluster/cluster-policy.js.map +1 -1
  5. package/dist/src/cluster/cluster-repo.d.ts +3 -3
  6. package/dist/src/cluster/cluster-repo.js +3 -3
  7. package/dist/src/cluster/cluster-size-coupling.d.ts +28 -0
  8. package/dist/src/cluster/cluster-size-coupling.d.ts.map +1 -0
  9. package/dist/src/cluster/cluster-size-coupling.js +35 -0
  10. package/dist/src/cluster/cluster-size-coupling.js.map +1 -0
  11. package/dist/src/cluster/quorum-restore.d.ts +6 -0
  12. package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
  13. package/dist/src/cluster/quorum-restore.js +1 -1
  14. package/dist/src/cluster/quorum-restore.js.map +1 -1
  15. package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
  16. package/dist/src/cluster/reconcile-block.js +15 -3
  17. package/dist/src/cluster/reconcile-block.js.map +1 -1
  18. package/dist/src/index.d.ts +2 -0
  19. package/dist/src/index.d.ts.map +1 -1
  20. package/dist/src/index.js +2 -0
  21. package/dist/src/index.js.map +1 -1
  22. package/dist/src/libp2p-key-network.d.ts +46 -5
  23. package/dist/src/libp2p-key-network.d.ts.map +1 -1
  24. package/dist/src/libp2p-key-network.js +40 -9
  25. package/dist/src/libp2p-key-network.js.map +1 -1
  26. package/dist/src/libp2p-node-base.d.ts +3 -2
  27. package/dist/src/libp2p-node-base.d.ts.map +1 -1
  28. package/dist/src/libp2p-node-base.js +834 -777
  29. package/dist/src/libp2p-node-base.js.map +1 -1
  30. package/dist/src/libp2p-node-rn.d.ts +2 -2
  31. package/dist/src/libp2p-node-rn.d.ts.map +1 -1
  32. package/dist/src/libp2p-node-rn.js.map +1 -1
  33. package/dist/src/libp2p-node.d.ts +2 -2
  34. package/dist/src/libp2p-node.d.ts.map +1 -1
  35. package/dist/src/libp2p-node.js.map +1 -1
  36. package/dist/src/network/network-manager-service.d.ts +2 -0
  37. package/dist/src/network/network-manager-service.d.ts.map +1 -1
  38. package/dist/src/network/network-manager-service.js +4 -0
  39. package/dist/src/network/network-manager-service.js.map +1 -1
  40. package/dist/src/optimystic-node.d.ts +35 -0
  41. package/dist/src/optimystic-node.d.ts.map +1 -0
  42. package/dist/src/optimystic-node.js +2 -0
  43. package/dist/src/optimystic-node.js.map +1 -0
  44. package/dist/src/repo/coordinator-repo.d.ts +16 -5
  45. package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
  46. package/dist/src/repo/coordinator-repo.js +24 -8
  47. package/dist/src/repo/coordinator-repo.js.map +1 -1
  48. package/dist/src/rn.d.ts +2 -0
  49. package/dist/src/rn.d.ts.map +1 -1
  50. package/dist/src/rn.js +2 -0
  51. package/dist/src/rn.js.map +1 -1
  52. package/dist/src/storage/block-storage.d.ts.map +1 -1
  53. package/dist/src/storage/block-storage.js +57 -5
  54. package/dist/src/storage/block-storage.js.map +1 -1
  55. package/dist/src/storage/i-block-storage.d.ts +20 -1
  56. package/dist/src/storage/i-block-storage.d.ts.map +1 -1
  57. package/dist/src/storage/storage-repo.d.ts +56 -3
  58. package/dist/src/storage/storage-repo.d.ts.map +1 -1
  59. package/dist/src/storage/storage-repo.js +124 -18
  60. package/dist/src/storage/storage-repo.js.map +1 -1
  61. package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
  62. package/dist/src/testing/raw-storage-conformance.js +17 -0
  63. package/dist/src/testing/raw-storage-conformance.js.map +1 -1
  64. package/package.json +2 -2
  65. package/readme.md +41 -26
  66. package/src/cluster/cluster-policy.ts +55 -4
  67. package/src/cluster/cluster-repo.ts +3 -3
  68. package/src/cluster/cluster-size-coupling.ts +45 -0
  69. package/src/cluster/quorum-restore.ts +1 -1
  70. package/src/cluster/reconcile-block.ts +15 -3
  71. package/src/index.ts +2 -0
  72. package/src/libp2p-key-network.ts +41 -9
  73. package/src/libp2p-node-base.ts +907 -847
  74. package/src/libp2p-node-rn.ts +2 -2
  75. package/src/libp2p-node.ts +2 -2
  76. package/src/network/network-manager-service.ts +5 -0
  77. package/src/optimystic-node.ts +36 -0
  78. package/src/repo/coordinator-repo.ts +24 -8
  79. package/src/rn.ts +2 -0
  80. package/src/storage/block-storage.ts +59 -6
  81. package/src/storage/i-block-storage.ts +20 -1
  82. package/src/storage/storage-repo.ts +129 -18
  83. package/src/testing/raw-storage-conformance.ts +20 -0
@@ -45,6 +45,15 @@ import { type ClusterConsensusConfig } from "@optimystic/db-core";
45
45
  * must not drift.
46
46
  */
47
47
  export declare const minAbsoluteClusterSize = 2;
48
+ /**
49
+ * Default replication factor / target cohort breadth when the operator declares no `clusterSize`.
50
+ *
51
+ * Exported (and re-exported from the package root) rather than left inline because a caller that
52
+ * must construct a `Libp2pKeyPeerNetwork` for a node it did not build has to state a cluster size —
53
+ * the constructor no longer supplies one — and the only defensible answer is "whatever a node built
54
+ * here would have resolved to". Repeating the literal is how the two drifted last time.
55
+ */
56
+ export declare const DEFAULT_CLUSTER_SIZE = 10;
48
57
  /**
49
58
  * The operator-facing cluster knobs. `NodeOptions` (`libp2p-node-base.ts`) intersects this rather
50
59
  * than restating it, so a knob added here is one `resolveClusterPolicy` is guaranteed to see — a
@@ -105,8 +114,10 @@ export type ResolvedClusterPolicy = ClusterConsensusConfig & {
105
114
  repairCorroborationClusterSize: number;
106
115
  };
107
116
  /**
108
- * Apply every cluster-policy default a node needs. Pure — same options in, same numbers out so the
109
- * composition root's behavior is unit-testable (`test/cluster-policy.spec.ts`).
117
+ * Apply every cluster-policy default a node needs. Same options in, same numbers out, so the
118
+ * composition root's behavior is unit-testable (`test/cluster-policy.spec.ts`). Its one side effect
119
+ * is the `assumed-cluster-size-unset` advisory below, which lives here because this is the only place
120
+ * that knows the resolution produced a self-defeating combination.
110
121
  */
111
122
  export declare function resolveClusterPolicy(options: ClusterPolicyOptions): ResolvedClusterPolicy;
112
123
  //# sourceMappingURL=cluster-policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cluster-policy.d.ts","sourceRoot":"","sources":["../../../src/cluster/cluster-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAEpG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE;QACf,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,0DAA0D;QAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,sGAAsG;QACtG,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC;;;;;WAKG;QACH,4BAA4B,CAAC,EAAE,OAAO,CAAC;QACvC;;;;;;;;;;;WAWG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACF;AAED,kGAAkG;AAClG,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG;IAC5D,oFAAoF;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,8BAA8B,EAAE,MAAM,CAAC;CACvC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,CAoCzF"}
1
+ {"version":3,"file":"cluster-policy.d.ts","sourceRoot":"","sources":["../../../src/cluster/cluster-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAMpG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE;QACf,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,0DAA0D;QAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,sGAAsG;QACtG,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC;;;;;WAKG;QACH,4BAA4B,CAAC,EAAE,OAAO,CAAC;QACvC;;;;;;;;;;;WAWG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACF;AAED,kGAAkG;AAClG,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG;IAC5D,oFAAoF;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,8BAA8B,EAAE,MAAM,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,CAuEzF"}
@@ -1,4 +1,7 @@
1
1
  import { DEFAULT_SUPER_MAJORITY_THRESHOLD } from "@optimystic/db-core";
2
+ import { createLogger } from "../logger.js";
3
+ import { CORROBORATION_FLOOR } from "./quorum-restore.js";
4
+ const log = createLogger('cluster-policy');
2
5
  /**
3
6
  * Resolves the operator-facing cluster knobs (`clusterSize`, `clusterPolicy.*`) into the concrete
4
7
  * numbers the consensus and block-restoration paths run on.
@@ -46,8 +49,19 @@ import { DEFAULT_SUPER_MAJORITY_THRESHOLD } from "@optimystic/db-core";
46
49
  */
47
50
  export const minAbsoluteClusterSize = 2;
48
51
  /**
49
- * Apply every cluster-policy default a node needs. Pure same options in, same numbers out — so the
50
- * composition root's behavior is unit-testable (`test/cluster-policy.spec.ts`).
52
+ * Default replication factor / target cohort breadth when the operator declares no `clusterSize`.
53
+ *
54
+ * Exported (and re-exported from the package root) rather than left inline because a caller that
55
+ * must construct a `Libp2pKeyPeerNetwork` for a node it did not build has to state a cluster size —
56
+ * the constructor no longer supplies one — and the only defensible answer is "whatever a node built
57
+ * here would have resolved to". Repeating the literal is how the two drifted last time.
58
+ */
59
+ export const DEFAULT_CLUSTER_SIZE = 10;
60
+ /**
61
+ * Apply every cluster-policy default a node needs. Same options in, same numbers out, so the
62
+ * composition root's behavior is unit-testable (`test/cluster-policy.spec.ts`). Its one side effect
63
+ * is the `assumed-cluster-size-unset` advisory below, which lives here because this is the only place
64
+ * that knows the resolution produced a self-defeating combination.
51
65
  */
52
66
  export function resolveClusterPolicy(options) {
53
67
  // undefined here means "the operator said nothing", which is the only case where the two
@@ -60,7 +74,40 @@ export function resolveClusterPolicy(options) {
60
74
  // rejects non-positive integers). If another composition root starts accepting unvalidated config,
61
75
  // clamp here rather than in each consumer.
62
76
  const declaredCohortSize = options.clusterPolicy?.assumedClusterSize;
63
- const clusterSize = options.clusterSize ?? 10;
77
+ const clusterSize = options.clusterSize ?? DEFAULT_CLUSTER_SIZE;
78
+ const repairCorroborationClusterSize = declaredCohortSize ?? clusterSize;
79
+ // Called once per node (resolveClusterPolicy runs once at construction), so this fires once per
80
+ // node startup, not per repair — a per-attempt warn on a busy node would be noise that gets
81
+ // filtered, defeating the point. Fires purely off configuration (not an observed cohort), so a
82
+ // deployment that genuinely runs `clusterSize` machines sees it too; worded as a conditional
83
+ // ("if you run fewer than N machines") rather than a fault for exactly that reason.
84
+ //
85
+ // The machine count in the message is CORROBORATION_FLOOR + 1, NOT repairCorroborationClusterSize:
86
+ // `corroboratorCapacity` caps only the FLOOR of two (`quorum-restore.ts`), so a cohort with two
87
+ // peers besides the reader meets it whatever the declared size. What an undeclared size costs is
88
+ // the relaxation below two, which is only reachable when repairCorroborationClusterSize <= 2.
89
+ // NOTE: only the UNDECLARED case warns. An operator who declares an assumedClusterSize larger than
90
+ // the cohort they actually run is equally unable to repair and gets no warning — deliberate, since
91
+ // a declaration is an explicit assertion and this function has no observed cohort to contradict it
92
+ // with. If `feat-admission-floor-from-observed-cohort-high-water-mark` ever lands (deriving the
93
+ // yardstick from observation), that warning becomes cheap and worth adding here.
94
+ if (declaredCohortSize === undefined && clusterSize > minAbsoluteClusterSize) {
95
+ const minimumSelfHealingDeployment = CORROBORATION_FLOOR + 1;
96
+ log('assumed-cluster-size-unset', {
97
+ clusterSize,
98
+ repairCorroborationClusterSize,
99
+ corroborationFloor: CORROBORATION_FLOOR,
100
+ minimumSelfHealingDeployment,
101
+ message: `No clusterPolicy.assumedClusterSize declared: block repair (read-repair and reconcile) requires ` +
102
+ `${CORROBORATION_FLOOR} distinct corroborating peers other than the reader, and that floor is ` +
103
+ `relaxed only for a cohort that DECLARES it is smaller — with ` +
104
+ `repairCorroborationClusterSize=${repairCorroborationClusterSize} it never relaxes. So a deployment ` +
105
+ `that actually runs fewer than ${minimumSelfHealingDeployment} machines can never supply the floor ` +
106
+ `and every repair declines, permanently. If you run fewer than ${minimumSelfHealingDeployment} ` +
107
+ `machines, set clusterPolicy.assumedClusterSize to your real cohort size; it does not lower ` +
108
+ `clusterSize=${clusterSize} (the replication factor). Larger deployments can ignore this.`
109
+ });
110
+ }
64
111
  return {
65
112
  superMajorityThreshold: options.clusterPolicy?.superMajorityThreshold ?? DEFAULT_SUPER_MAJORITY_THRESHOLD,
66
113
  simpleMajorityThreshold: 0.51,
@@ -82,7 +129,7 @@ export function resolveClusterPolicy(options) {
82
129
  // Repair corroboration floor, every repair. Defaults strict — to the replication factor — so an
83
130
  // unconfigured node cannot have its floor talked down to a single voter by a shrunken cohort
84
131
  // view. A genuinely small mesh declares its size (either field) to regain self-repair.
85
- repairCorroborationClusterSize: declaredCohortSize ?? clusterSize
132
+ repairCorroborationClusterSize
86
133
  };
87
134
  }
88
135
  //# sourceMappingURL=cluster-policy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cluster-policy.js","sourceRoot":"","sources":["../../../src/cluster/cluster-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAA+B,MAAM,qBAAqB,CAAC;AAEpG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AA+DxC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA6B;IACjE,yFAAyF;IACzF,4BAA4B;IAC5B,EAAE;IACF,mGAAmG;IACnG,8FAA8F;IAC9F,4FAA4F;IAC5F,8FAA8F;IAC9F,mGAAmG;IACnG,2CAA2C;IAC3C,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,kBAAkB,CAAC;IACrE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IAE9C,OAAO;QACN,sBAAsB,EAAE,OAAO,CAAC,aAAa,EAAE,sBAAsB,IAAI,gCAAgC;QACzG,uBAAuB,EAAE,IAAI;QAC7B,sBAAsB;QACtB,oBAAoB,EAAE,OAAO,CAAC,aAAa,EAAE,aAAa,IAAI,IAAI;QAClE,oBAAoB,EAAE,OAAO,CAAC,aAAa,EAAE,aAAa,IAAI,GAAG;QACjE,2FAA2F;QAC3F,oFAAoF;QACpF,4BAA4B,EAAE,OAAO,CAAC,aAAa,EAAE,4BAA4B,IAAI,KAAK;QAC1F,wBAAwB,EAAE,KAAK;QAC/B,8FAA8F;QAC9F,gGAAgG;QAChG,qFAAqF;QACrF,WAAW;QACX,+FAA+F;QAC/F,8FAA8F;QAC9F,0EAA0E;QAC1E,kBAAkB,EAAE,kBAAkB,IAAI,sBAAsB;QAChE,gGAAgG;QAChG,6FAA6F;QAC7F,uFAAuF;QACvF,8BAA8B,EAAE,kBAAkB,IAAI,WAAW;KACjE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"cluster-policy.js","sourceRoot":"","sources":["../../../src/cluster/cluster-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAA+B,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AA+DvC;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA6B;IACjE,yFAAyF;IACzF,4BAA4B;IAC5B,EAAE;IACF,mGAAmG;IACnG,8FAA8F;IAC9F,4FAA4F;IAC5F,8FAA8F;IAC9F,mGAAmG;IACnG,2CAA2C;IAC3C,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,kBAAkB,CAAC;IACrE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAChE,MAAM,8BAA8B,GAAG,kBAAkB,IAAI,WAAW,CAAC;IAEzE,gGAAgG;IAChG,4FAA4F;IAC5F,+FAA+F;IAC/F,6FAA6F;IAC7F,oFAAoF;IACpF,EAAE;IACF,mGAAmG;IACnG,gGAAgG;IAChG,iGAAiG;IACjG,8FAA8F;IAC9F,mGAAmG;IACnG,mGAAmG;IACnG,mGAAmG;IACnG,gGAAgG;IAChG,iFAAiF;IACjF,IAAI,kBAAkB,KAAK,SAAS,IAAI,WAAW,GAAG,sBAAsB,EAAE,CAAC;QAC9E,MAAM,4BAA4B,GAAG,mBAAmB,GAAG,CAAC,CAAC;QAC7D,GAAG,CAAC,4BAA4B,EAAE;YACjC,WAAW;YACX,8BAA8B;YAC9B,kBAAkB,EAAE,mBAAmB;YACvC,4BAA4B;YAC5B,OAAO,EACN,kGAAkG;gBAClG,GAAG,mBAAmB,yEAAyE;gBAC/F,+DAA+D;gBAC/D,kCAAkC,8BAA8B,qCAAqC;gBACrG,iCAAiC,4BAA4B,uCAAuC;gBACpG,iEAAiE,4BAA4B,GAAG;gBAChG,6FAA6F;gBAC7F,eAAe,WAAW,gEAAgE;SAC3F,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACN,sBAAsB,EAAE,OAAO,CAAC,aAAa,EAAE,sBAAsB,IAAI,gCAAgC;QACzG,uBAAuB,EAAE,IAAI;QAC7B,sBAAsB;QACtB,oBAAoB,EAAE,OAAO,CAAC,aAAa,EAAE,aAAa,IAAI,IAAI;QAClE,oBAAoB,EAAE,OAAO,CAAC,aAAa,EAAE,aAAa,IAAI,GAAG;QACjE,2FAA2F;QAC3F,oFAAoF;QACpF,4BAA4B,EAAE,OAAO,CAAC,aAAa,EAAE,4BAA4B,IAAI,KAAK;QAC1F,wBAAwB,EAAE,KAAK;QAC/B,8FAA8F;QAC9F,gGAAgG;QAChG,qFAAqF;QACrF,WAAW;QACX,+FAA+F;QAC/F,8FAA8F;QAC9F,0EAA0E;QAC1E,kBAAkB,EAAE,kBAAkB,IAAI,sBAAsB;QAChE,gGAAgG;QAChG,6FAA6F;QAC7F,uFAAuF;QACvF,8BAA8B;KAC9B,CAAC;AACH,CAAC"}
@@ -267,9 +267,9 @@ export declare class ClusterMember implements ICluster {
267
267
  *
268
268
  * NOTE: partition safety needs `2 · membershipAdmissionFraction · superMajorityThreshold > 1` — each
269
269
  * side of a split must recruit `fraction · threshold · K` distinct honest members, and two sides cannot
270
- * both find them in one K-peer cluster. At the shipped defaults (0.75 · 0.67) that product is 1.005 —
271
- * true, but with almost no margin. If either default is ever lowered, re-check Theorem 2 in
272
- * `docs/correctness.md` before shipping it.
270
+ * both find them in one K-peer cluster. At the shipped defaults (0.75 · 0.75 both default to
271
+ * `DEFAULT_SUPER_MAJORITY_THRESHOLD` / `membershipAdmissionFraction`'s own default) that product is
272
+ * 1.125. If either default is ever lowered, re-check Theorem 2 in `docs/correctness.md` before shipping it.
273
273
  */
274
274
  private admissionFloor;
275
275
  /**
@@ -779,9 +779,9 @@ export class ClusterMember {
779
779
  *
780
780
  * NOTE: partition safety needs `2 · membershipAdmissionFraction · superMajorityThreshold > 1` — each
781
781
  * side of a split must recruit `fraction · threshold · K` distinct honest members, and two sides cannot
782
- * both find them in one K-peer cluster. At the shipped defaults (0.75 · 0.67) that product is 1.005 —
783
- * true, but with almost no margin. If either default is ever lowered, re-check Theorem 2 in
784
- * `docs/correctness.md` before shipping it.
782
+ * both find them in one K-peer cluster. At the shipped defaults (0.75 · 0.75 both default to
783
+ * `DEFAULT_SUPER_MAJORITY_THRESHOLD` / `membershipAdmissionFraction`'s own default) that product is
784
+ * 1.125. If either default is ever lowered, re-check Theorem 2 in `docs/correctness.md` before shipping it.
785
785
  */
786
786
  admissionFloor(k) {
787
787
  const scaled = Math.ceil(this.membershipAdmissionFraction * k);
@@ -0,0 +1,28 @@
1
+ /** A component that exposes the cluster size it actually resolved to. */
2
+ export interface HasEffectiveClusterSize {
3
+ readonly effectiveClusterSize: number;
4
+ }
5
+ /**
6
+ * Fail-fast coupling check for a live node's cluster-size wiring, mirroring
7
+ * `assertSuperMajorityCoupling`.
8
+ *
9
+ * `resolveClusterPolicy` (`cluster/cluster-policy.ts`) is the single place that settles the
10
+ * replication factor / target cohort breadth (`clusterSize`). Every consumer that resolves its
11
+ * own cluster size — `Libp2pKeyPeerNetwork` (peer selection) and `NetworkManagerService` (ring
12
+ * sizing) — must be constructed from that SAME resolved value, or the membership admission
13
+ * gate's "is this declared peer set suspiciously small?" yardstick silently diverges from the
14
+ * cohort width peer selection actually assembles (ticket
15
+ * `bug-cluster-size-resolution-single-source`: an unconfigured node ran peer selection at 16
16
+ * while consensus believed full size was 10, so a cohort that had quietly lost six members still
17
+ * measured as full).
18
+ *
19
+ * On a live node both are constructed from `resolveClusterPolicy(options).clusterSize`, so this
20
+ * check normally passes. It exists to catch *future* drift — a call site reverting to its own
21
+ * default, a new consumer added without threading the resolved value — by throwing at
22
+ * construction with every resolved value and its source, rather than letting the node come up
23
+ * mismatched.
24
+ *
25
+ * @throws Error naming the resolved size and every consumer that disagrees with it.
26
+ */
27
+ export declare function assertClusterSizeCoupling(resolvedClusterSize: number, consumers: Record<string, HasEffectiveClusterSize | undefined>): void;
28
+ //# sourceMappingURL=cluster-size-coupling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-size-coupling.d.ts","sourceRoot":"","sources":["../../../src/cluster/cluster-size-coupling.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CACxC,mBAAmB,EAAE,MAAM,EAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,GAAG,SAAS,CAAC,GAC5D,IAAI,CAcN"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Fail-fast coupling check for a live node's cluster-size wiring, mirroring
3
+ * `assertSuperMajorityCoupling`.
4
+ *
5
+ * `resolveClusterPolicy` (`cluster/cluster-policy.ts`) is the single place that settles the
6
+ * replication factor / target cohort breadth (`clusterSize`). Every consumer that resolves its
7
+ * own cluster size — `Libp2pKeyPeerNetwork` (peer selection) and `NetworkManagerService` (ring
8
+ * sizing) — must be constructed from that SAME resolved value, or the membership admission
9
+ * gate's "is this declared peer set suspiciously small?" yardstick silently diverges from the
10
+ * cohort width peer selection actually assembles (ticket
11
+ * `bug-cluster-size-resolution-single-source`: an unconfigured node ran peer selection at 16
12
+ * while consensus believed full size was 10, so a cohort that had quietly lost six members still
13
+ * measured as full).
14
+ *
15
+ * On a live node both are constructed from `resolveClusterPolicy(options).clusterSize`, so this
16
+ * check normally passes. It exists to catch *future* drift — a call site reverting to its own
17
+ * default, a new consumer added without threading the resolved value — by throwing at
18
+ * construction with every resolved value and its source, rather than letting the node come up
19
+ * mismatched.
20
+ *
21
+ * @throws Error naming the resolved size and every consumer that disagrees with it.
22
+ */
23
+ export function assertClusterSizeCoupling(resolvedClusterSize, consumers) {
24
+ const mismatches = Object.entries(consumers)
25
+ .filter((entry) => entry[1] !== undefined)
26
+ .filter(([, consumer]) => consumer.effectiveClusterSize !== resolvedClusterSize)
27
+ .map(([name, consumer]) => `${name} resolved ${consumer.effectiveClusterSize}`);
28
+ if (mismatches.length > 0) {
29
+ throw new Error(`Cluster size mismatch at node startup: resolveClusterPolicy() produced clusterSize=${resolvedClusterSize}, ` +
30
+ `but ${mismatches.join(', ')}. Every cluster-size consumer must be constructed from the SAME resolved ` +
31
+ `value (see cluster/cluster-policy.ts), or the membership admission gate's yardstick can diverge from ` +
32
+ `the cohort width peer selection actually assembles.`);
33
+ }
34
+ }
35
+ //# sourceMappingURL=cluster-size-coupling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-size-coupling.js","sourceRoot":"","sources":["../../../src/cluster/cluster-size-coupling.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,yBAAyB,CACxC,mBAA2B,EAC3B,SAA8D;IAE9D,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAC1C,MAAM,CAAC,CAAC,KAAK,EAA8C,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SACrF,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,oBAAoB,KAAK,mBAAmB,CAAC;SAC/E,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,aAAa,QAAQ,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAEjF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACd,sFAAsF,mBAAmB,IAAI;YAC7G,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,2EAA2E;YACvG,uGAAuG;YACvG,qDAAqD,CACrD,CAAC;IACH,CAAC;AACF,CAAC"}
@@ -27,6 +27,12 @@ export interface QuorumRev {
27
27
  /** Distinct peer-ids that voted for this exact (rev, actionId). */
28
28
  supporters: string[];
29
29
  }
30
+ /**
31
+ * Votes a claim needs when the cohort is big enough to supply them: a claim must be
32
+ * seconded by a second, independent peer. See {@link quorumSize} for the cap that
33
+ * applies when the cohort is smaller than this.
34
+ */
35
+ export declare const CORROBORATION_FLOOR = 2;
30
36
  /**
31
37
  * Number of distinct corroborating votes required to accept a claim:
32
38
  * `floor(simpleMajorityThreshold × responderCount)`, never below
@@ -1 +1 @@
1
- {"version":3,"file":"quorum-restore.d.ts","sourceRoot":"","sources":["../../../src/cluster/quorum-restore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD;;;;;;;;;;;;;GAaG;AAEH,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACxB,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,UAAU,EAAE,MAAM,EAAE,CAAC;CACrB;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACzB,cAAc,EAAE,MAAM,EACtB,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,GAAE,MAAiC,GACrD,MAAM,CAGR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,8BAA8B,EAAE,MAAM,GAAG,MAAM,CAE5G;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,QAAQ,EAAE,EAClB,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,CAAC,EAAE,MAAM,GAC3B,SAAS,GAAG,SAAS,CAkCvB;AAWD,2GAA2G;AAC3G,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAChC,UAAU,EAAE,kBAAkB,EAAE,EAChC,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,CAAC,EAAE,MAAM,GAC3B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuB7C"}
1
+ {"version":3,"file":"quorum-restore.d.ts","sourceRoot":"","sources":["../../../src/cluster/quorum-restore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD;;;;;;;;;;;;;GAaG;AAEH,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACxB,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,UAAU,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACzB,cAAc,EAAE,MAAM,EACtB,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,GAAE,MAAiC,GACrD,MAAM,CAGR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,8BAA8B,EAAE,MAAM,GAAG,MAAM,CAE5G;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,QAAQ,EAAE,EAClB,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,CAAC,EAAE,MAAM,GAC3B,SAAS,GAAG,SAAS,CAkCvB;AAWD,2GAA2G;AAC3G,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAChC,UAAU,EAAE,kBAAkB,EAAE,EAChC,uBAAuB,EAAE,MAAM,EAC/B,oBAAoB,CAAC,EAAE,MAAM,GAC3B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuB7C"}
@@ -5,7 +5,7 @@ import { toString as uint8ArrayToString } from 'uint8arrays';
5
5
  * seconded by a second, independent peer. See {@link quorumSize} for the cap that
6
6
  * applies when the cohort is smaller than this.
7
7
  */
8
- const CORROBORATION_FLOOR = 2;
8
+ export const CORROBORATION_FLOOR = 2;
9
9
  /**
10
10
  * Number of distinct corroborating votes required to accept a claim:
11
11
  * `floor(simpleMajorityThreshold × responderCount)`, never below
@@ -1 +1 @@
1
- {"version":3,"file":"quorum-restore.js","sourceRoot":"","sources":["../../../src/cluster/quorum-restore.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAiC7D;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CACzB,cAAsB,EACtB,uBAA+B,EAC/B,uBAA+B,MAAM,CAAC,iBAAiB;IAEvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC/E,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,uBAAuB,GAAG,cAAc,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,oBAAoB,CAAC,eAAuB,EAAE,8BAAsC;IACnG,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,8BAA8B,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAC9B,MAAkB,EAClB,uBAA+B,EAC/B,oBAA6B;IAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsE,CAAC;IAC7F,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACxB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,EAAE,CAAC;YACR,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YAChE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,uBAAuB,EAAE,oBAAoB,CAAC,CAAC;IAE1F,iFAAiF;IACjF,mFAAmF;IACnF,iFAAiF;IACjF,oFAAoF;IACpF,iFAAiF;IACjF,qFAAqF;IACrF,QAAQ;IACR,IAAI,IAA4E,CAAC;IACjF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAChE,IAAI,GAAG,CAAC,CAAC;QACV,CAAC;IACF,CAAC;IACD,OAAO,IAAI;QACV,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE;QAC9E,CAAC,CAAC,SAAS,CAAC;AACd,CAAC;AAED,qHAAqH;AACrH,SAAS,aAAa,CAAC,KAAc;IACpC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACrC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAA0B,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACjG,CAAC,CAAC,CAAC,CACJ,CAAC;AACH,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAa;IACrD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACvD,CAAC;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAChC,UAAgC,EAChC,uBAA+B,EAC/B,oBAA6B;IAE7B,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE9C,+FAA+F;IAC/F,2DAA2D;IAC3D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsD,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;YACR,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACvB,CAAC;QACD,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,uBAAuB,EAAE,oBAAoB,CAAC,CAAC;IACtF,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC;IACrF,uFAAuF;IACvF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;IAClC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"quorum-restore.js","sourceRoot":"","sources":["../../../src/cluster/quorum-restore.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-block.d.ts","sourceRoot":"","sources":["../../../src/cluster/reconcile-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAU9D;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAWzC,wGAAwG;AACxG,MAAM,WAAW,kBAAkB;IAClC,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACtF,uEAAuE;IACvE,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3F,oFAAoF;IACpF,uBAAuB,EAAE,MAAM,CAAC;IAChC;;;;;;;;OAQG;IACH,8BAA8B,EAAE,MAAM,CAAC;IACvC,iFAAiF;IACjF,UAAU,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;CACjD;AAmFD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,sBAAsB,CA+BrF"}
1
+ {"version":3,"file":"reconcile-block.d.ts","sourceRoot":"","sources":["../../../src/cluster/reconcile-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAU9D;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAWzC,wGAAwG;AACxG,MAAM,WAAW,kBAAkB;IAClC,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACtF,uEAAuE;IACvE,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3F,oFAAoF;IACpF,uBAAuB,EAAE,MAAM,CAAC;IAChC;;;;;;;;OAQG;IACH,8BAA8B,EAAE,MAAM,CAAC;IACvC,iFAAiF;IACjF,UAAU,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;CACjD;AAmFD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,sBAAsB,CA2CrF"}
@@ -1,5 +1,5 @@
1
1
  import { PenaltyReason } from "../reputation/types.js";
2
- import { selectQuorumRev, selectQuorumBlock, canonicalBlockHash, corroboratorCapacity } from "./quorum-restore.js";
2
+ import { selectQuorumRev, selectQuorumBlock, canonicalBlockHash, corroboratorCapacity, quorumSize } from "./quorum-restore.js";
3
3
  import { createLogger } from '../logger.js';
4
4
  const log = createLogger('reconcile-block');
5
5
  /**
@@ -116,13 +116,25 @@ export function createReconcileBlock(deps) {
116
116
  const selected = selectQuorumRev(revClaims, deps.simpleMajorityThreshold, capacity);
117
117
  if (!selected) {
118
118
  // Leave the block behind; churn/rebalance and the next commit retry.
119
- log('reconcile:no-rev-quorum', { blockId, rev: committed.rev, responders: revClaims.length, capacity });
119
+ log('reconcile:no-rev-quorum', {
120
+ blockId,
121
+ rev: committed.rev,
122
+ responders: revClaims.length,
123
+ required: quorumSize(revClaims.length, deps.simpleMajorityThreshold, capacity),
124
+ repairCorroborationClusterSize: deps.repairCorroborationClusterSize
125
+ });
120
126
  return;
121
127
  }
122
128
  const hashCandidates = await hashCarriers(candidates, selected);
123
129
  const agreed = selectQuorumBlock(hashCandidates, deps.simpleMajorityThreshold, capacity);
124
130
  if (!agreed) {
125
- log('reconcile:no-content-quorum', { blockId, rev: selected.rev, carriers: hashCandidates.length, capacity });
131
+ log('reconcile:no-content-quorum', {
132
+ blockId,
133
+ rev: selected.rev,
134
+ carriers: hashCandidates.length,
135
+ required: quorumSize(hashCandidates.length, deps.simpleMajorityThreshold, capacity),
136
+ repairCorroborationClusterSize: deps.repairCorroborationClusterSize
137
+ });
126
138
  return;
127
139
  }
128
140
  penalizeContradictingContent(deps.reputation, hashCandidates, agreed.hash, blockId);
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-block.js","sourceRoot":"","sources":["../../../src/cluster/reconcile-block.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reconcile-block.js","sourceRoot":"","sources":["../../../src/cluster/reconcile-block.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export * from "./cluster/client.js";
2
2
  export * from "./cluster/cluster-repo.js";
3
+ export * from "./cluster/cluster-policy.js";
3
4
  export * from "./cluster/commit-cert.js";
4
5
  export * from "./cluster/service.js";
5
6
  export * from "./cluster/rebalance-monitor.js";
@@ -31,6 +32,7 @@ export * from "./sync/service.js";
31
32
  export * from "./it-utility.js";
32
33
  export * from "./libp2p-key-network.js";
33
34
  export * from "./libp2p-node.js";
35
+ export * from "./optimystic-node.js";
34
36
  export * from "./routing/responsibility.js";
35
37
  export * from "./routing/libp2p-known-peers.js";
36
38
  export * from "./network/network-manager-service.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./cluster/client.js";
2
2
  export * from "./cluster/cluster-repo.js";
3
+ export * from "./cluster/cluster-policy.js";
3
4
  export * from "./cluster/commit-cert.js";
4
5
  export * from "./cluster/service.js";
5
6
  export * from "./cluster/rebalance-monitor.js";
@@ -31,6 +32,7 @@ export * from "./sync/service.js";
31
32
  export * from "./it-utility.js";
32
33
  export * from "./libp2p-key-network.js";
33
34
  export * from "./libp2p-node.js";
35
+ export * from "./optimystic-node.js";
34
36
  export * from "./routing/responsibility.js";
35
37
  export * from "./routing/libp2p-known-peers.js";
36
38
  export * from "./network/network-manager-service.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC"}
@@ -121,6 +121,13 @@ export interface SelfCoordinationDecision {
121
121
  }
122
122
  export declare class Libp2pKeyPeerNetwork implements IKeyNetwork, IPeerNetwork {
123
123
  private readonly libp2p;
124
+ /**
125
+ * Replication factor / target cohort breadth for peer selection. REQUIRED, deliberately:
126
+ * a silent default here meant a caller that did not know the node's cluster size quietly
127
+ * selected a different-width cohort than the node's own consensus path used for the same
128
+ * key. Reuse the node's own instance (`node.keyNetwork`) where one exists; a caller that
129
+ * genuinely must construct standalone passes `DEFAULT_CLUSTER_SIZE` (`cluster/cluster-policy.ts`).
130
+ */
124
131
  private readonly clusterSize;
125
132
  private readonly reputation?;
126
133
  /**
@@ -128,8 +135,17 @@ export declare class Libp2pKeyPeerNetwork implements IKeyNetwork, IPeerNetwork {
128
135
  * provided, coordinator/cohort selection is scoped to peers that serve THIS
129
136
  * network's `cluster`/`repo` protocol, so a peer that only belongs to another
130
137
  * network sharing the same physical nodes/bootstraps is never chosen. When
131
- * ABSENT, the membership filter is disabled (today's exact behavior) — required
132
- * for backward compatibility because most call sites don't know the network name.
138
+ * ABSENT, the membership filter is disabled.
139
+ *
140
+ * NOTE: optional for the same reason `clusterSize` used to be — "most call sites don't
141
+ * know the network name" — and that reason no longer holds: both production sites now
142
+ * pass it (`libp2p-node-base.ts`, and the foreign-node fallback in the Quereus
143
+ * collection-factory), and only the mock-based cases in `test/libp2p-key-network.spec.ts`
144
+ * omit it. So a caller omitting it today gets the filter silently off, exactly the shape
145
+ * that let a second key network be built with a wrong cohort width. Left optional because
146
+ * making it required would touch ~50 construction sites in that one spec and no reachable
147
+ * caller is affected. Make it required (or take the whole list as an options bag) the
148
+ * moment a THIRD production construction site appears, or when that spec is rewritten.
133
149
  */
134
150
  private readonly protocolPrefix?;
135
151
  private readonly selfCoordinationConfig;
@@ -138,16 +154,41 @@ export declare class Libp2pKeyPeerNetwork implements IKeyNetwork, IPeerNetwork {
138
154
  private consecutiveIsolatedSessions;
139
155
  private readonly networkMode;
140
156
  private readonly persistence?;
141
- constructor(libp2p: Libp2p, clusterSize?: number, selfCoordinationConfig?: SelfCoordinationConfig, networkMode?: NetworkMode, persistence?: NetworkStatePersistence, reputation?: IPeerReputation | undefined,
157
+ constructor(libp2p: Libp2p,
158
+ /**
159
+ * Replication factor / target cohort breadth for peer selection. REQUIRED, deliberately:
160
+ * a silent default here meant a caller that did not know the node's cluster size quietly
161
+ * selected a different-width cohort than the node's own consensus path used for the same
162
+ * key. Reuse the node's own instance (`node.keyNetwork`) where one exists; a caller that
163
+ * genuinely must construct standalone passes `DEFAULT_CLUSTER_SIZE` (`cluster/cluster-policy.ts`).
164
+ */
165
+ clusterSize: number, selfCoordinationConfig?: SelfCoordinationConfig, networkMode?: NetworkMode, persistence?: NetworkStatePersistence, reputation?: IPeerReputation | undefined,
142
166
  /**
143
167
  * Network-namespaced protocol prefix (`/optimystic/<networkName>`). When
144
168
  * provided, coordinator/cohort selection is scoped to peers that serve THIS
145
169
  * network's `cluster`/`repo` protocol, so a peer that only belongs to another
146
170
  * network sharing the same physical nodes/bootstraps is never chosen. When
147
- * ABSENT, the membership filter is disabled (today's exact behavior) — required
148
- * for backward compatibility because most call sites don't know the network name.
171
+ * ABSENT, the membership filter is disabled.
172
+ *
173
+ * NOTE: optional for the same reason `clusterSize` used to be — "most call sites don't
174
+ * know the network name" — and that reason no longer holds: both production sites now
175
+ * pass it (`libp2p-node-base.ts`, and the foreign-node fallback in the Quereus
176
+ * collection-factory), and only the mock-based cases in `test/libp2p-key-network.spec.ts`
177
+ * omit it. So a caller omitting it today gets the filter silently off, exactly the shape
178
+ * that let a second key network be built with a wrong cohort width. Left optional because
179
+ * making it required would touch ~50 construction sites in that one spec and no reachable
180
+ * caller is affected. Make it required (or take the whole list as an options bag) the
181
+ * moment a THIRD production construction site appears, or when that spec is rewritten.
149
182
  */
150
183
  protocolPrefix?: string | undefined);
184
+ /** The cluster size this instance actually resolved to, for `assertClusterSizeCoupling`. */
185
+ get effectiveClusterSize(): number;
186
+ /**
187
+ * The network-namespaced protocol prefix (`/optimystic/<networkName>`) selection is scoped to,
188
+ * or `undefined` when the network-membership filter is off. Readable so a spec can assert the
189
+ * node's attached instance really is network-scoped without reaching into a private field.
190
+ */
191
+ get effectiveProtocolPrefix(): string | undefined;
151
192
  private readonly coordinatorCache;
152
193
  private static readonly MAX_CACHE_ENTRIES;
153
194
  private readonly log;
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p-key-network.d.ts","sourceRoot":"","sources":["../../src/libp2p-key-network.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libp2p-key-network.d.ts","sourceRoot":"","sources":["../../src/libp2p-key-network.ts"],"names":[],"mappings":"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"}
@@ -54,26 +54,45 @@ export class Libp2pKeyPeerNetwork {
54
54
  consecutiveIsolatedSessions = 0;
55
55
  networkMode;
56
56
  persistence;
57
- constructor(libp2p, clusterSize = 16, selfCoordinationConfig, networkMode, persistence, reputation,
57
+ // NOTE: seven positional parameters, and the list stays that way for now — converting to an
58
+ // options bag would touch ~50 construction sites in `test/libp2p-key-network.spec.ts` alone.
59
+ // Revisit if an eighth parameter is ever needed, or if that spec is being rewritten anyway.
60
+ constructor(libp2p,
61
+ /**
62
+ * Replication factor / target cohort breadth for peer selection. REQUIRED, deliberately:
63
+ * a silent default here meant a caller that did not know the node's cluster size quietly
64
+ * selected a different-width cohort than the node's own consensus path used for the same
65
+ * key. Reuse the node's own instance (`node.keyNetwork`) where one exists; a caller that
66
+ * genuinely must construct standalone passes `DEFAULT_CLUSTER_SIZE` (`cluster/cluster-policy.ts`).
67
+ */
68
+ clusterSize, selfCoordinationConfig, networkMode, persistence, reputation,
58
69
  /**
59
70
  * Network-namespaced protocol prefix (`/optimystic/<networkName>`). When
60
71
  * provided, coordinator/cohort selection is scoped to peers that serve THIS
61
72
  * network's `cluster`/`repo` protocol, so a peer that only belongs to another
62
73
  * network sharing the same physical nodes/bootstraps is never chosen. When
63
- * ABSENT, the membership filter is disabled (today's exact behavior) — required
64
- * for backward compatibility because most call sites don't know the network name.
74
+ * ABSENT, the membership filter is disabled.
75
+ *
76
+ * NOTE: optional for the same reason `clusterSize` used to be — "most call sites don't
77
+ * know the network name" — and that reason no longer holds: both production sites now
78
+ * pass it (`libp2p-node-base.ts`, and the foreign-node fallback in the Quereus
79
+ * collection-factory), and only the mock-based cases in `test/libp2p-key-network.spec.ts`
80
+ * omit it. So a caller omitting it today gets the filter silently off, exactly the shape
81
+ * that let a second key network be built with a wrong cohort width. Left optional because
82
+ * making it required would touch ~50 construction sites in that one spec and no reachable
83
+ * caller is affected. Make it required (or take the whole list as an options bag) the
84
+ * moment a THIRD production construction site appears, or when that spec is rewritten.
65
85
  */
66
86
  protocolPrefix) {
67
87
  this.libp2p = libp2p;
68
88
  this.clusterSize = clusterSize;
69
89
  this.reputation = reputation;
70
90
  this.protocolPrefix = protocolPrefix;
71
- // NOTE: no construction site in this repo passes a SelfCoordinationConfig — every one
72
- // leaves it `undefined` (libp2p-node-base.ts, quereus-plugin-optimystic's
73
- // collection-factory.ts and key-network.ts, reference-peer's cli.ts), so these
74
- // defaults are always what is in force and no operator can tune them. If tuning
75
- // `gracePeriodMs` is ever needed, those four sites have to thread the config through
76
- // first. Low urgency: a grace-period denial no longer fails the caller, it only costs
91
+ // NOTE: no production construction site in this repo passes a SelfCoordinationConfig —
92
+ // both leave it `undefined` (libp2p-node-base.ts, and the foreign-node fallback in
93
+ // quereus-plugin-optimystic's collection-factory.ts), so these defaults are always what
94
+ // is in force and no operator can tune them. If tuning `gracePeriodMs` is ever needed,
95
+ // those two sites have to thread the config through first. Low urgency: a grace-period denial no longer fails the caller, it only costs
77
96
  // a write the ~1s findCoordinator retry window before self-coordinating.
78
97
  this.selfCoordinationConfig = {
79
98
  gracePeriodMs: selfCoordinationConfig?.gracePeriodMs ?? 30_000,
@@ -84,6 +103,18 @@ export class Libp2pKeyPeerNetwork {
84
103
  this.persistence = persistence;
85
104
  this.setupConnectionTracking();
86
105
  }
106
+ /** The cluster size this instance actually resolved to, for `assertClusterSizeCoupling`. */
107
+ get effectiveClusterSize() {
108
+ return this.clusterSize;
109
+ }
110
+ /**
111
+ * The network-namespaced protocol prefix (`/optimystic/<networkName>`) selection is scoped to,
112
+ * or `undefined` when the network-membership filter is off. Readable so a spec can assert the
113
+ * node's attached instance really is network-scoped without reaching into a private field.
114
+ */
115
+ get effectiveProtocolPrefix() {
116
+ return this.protocolPrefix;
117
+ }
87
118
  // coordinator cache: key (base64url) -> peerId until expiry (bounded LRU-ish via Map insertion order)
88
119
  coordinatorCache = new Map();
89
120
  static MAX_CACHE_ENTRIES = 1000;