@optimystic/db-p2p 0.0.1

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 (189) hide show
  1. package/dist/index.min.js +52 -0
  2. package/dist/index.min.js.map +7 -0
  3. package/dist/src/cluster/client.d.ts +12 -0
  4. package/dist/src/cluster/client.d.ts.map +1 -0
  5. package/dist/src/cluster/client.js +65 -0
  6. package/dist/src/cluster/client.js.map +1 -0
  7. package/dist/src/cluster/cluster-repo.d.ts +79 -0
  8. package/dist/src/cluster/cluster-repo.d.ts.map +1 -0
  9. package/dist/src/cluster/cluster-repo.js +613 -0
  10. package/dist/src/cluster/cluster-repo.js.map +1 -0
  11. package/dist/src/cluster/partition-detector.d.ts +59 -0
  12. package/dist/src/cluster/partition-detector.d.ts.map +1 -0
  13. package/dist/src/cluster/partition-detector.js +129 -0
  14. package/dist/src/cluster/partition-detector.js.map +1 -0
  15. package/dist/src/cluster/service.d.ts +49 -0
  16. package/dist/src/cluster/service.d.ts.map +1 -0
  17. package/dist/src/cluster/service.js +107 -0
  18. package/dist/src/cluster/service.js.map +1 -0
  19. package/dist/src/index.d.ts +29 -0
  20. package/dist/src/index.d.ts.map +1 -0
  21. package/dist/src/index.js +29 -0
  22. package/dist/src/index.js.map +1 -0
  23. package/dist/src/it-utility.d.ts +4 -0
  24. package/dist/src/it-utility.d.ts.map +1 -0
  25. package/dist/src/it-utility.js +32 -0
  26. package/dist/src/it-utility.js.map +1 -0
  27. package/dist/src/libp2p-key-network.d.ts +59 -0
  28. package/dist/src/libp2p-key-network.d.ts.map +1 -0
  29. package/dist/src/libp2p-key-network.js +278 -0
  30. package/dist/src/libp2p-key-network.js.map +1 -0
  31. package/dist/src/libp2p-node.d.ts +28 -0
  32. package/dist/src/libp2p-node.d.ts.map +1 -0
  33. package/dist/src/libp2p-node.js +270 -0
  34. package/dist/src/libp2p-node.js.map +1 -0
  35. package/dist/src/logger.d.ts +3 -0
  36. package/dist/src/logger.d.ts.map +1 -0
  37. package/dist/src/logger.js +6 -0
  38. package/dist/src/logger.js.map +1 -0
  39. package/dist/src/network/get-network-manager.d.ts +4 -0
  40. package/dist/src/network/get-network-manager.d.ts.map +1 -0
  41. package/dist/src/network/get-network-manager.js +17 -0
  42. package/dist/src/network/get-network-manager.js.map +1 -0
  43. package/dist/src/network/network-manager-service.d.ts +82 -0
  44. package/dist/src/network/network-manager-service.d.ts.map +1 -0
  45. package/dist/src/network/network-manager-service.js +283 -0
  46. package/dist/src/network/network-manager-service.js.map +1 -0
  47. package/dist/src/peer-utils.d.ts +2 -0
  48. package/dist/src/peer-utils.d.ts.map +1 -0
  49. package/dist/src/peer-utils.js +28 -0
  50. package/dist/src/peer-utils.js.map +1 -0
  51. package/dist/src/protocol-client.d.ts +12 -0
  52. package/dist/src/protocol-client.d.ts.map +1 -0
  53. package/dist/src/protocol-client.js +34 -0
  54. package/dist/src/protocol-client.js.map +1 -0
  55. package/dist/src/repo/client.d.ts +17 -0
  56. package/dist/src/repo/client.d.ts.map +1 -0
  57. package/dist/src/repo/client.js +82 -0
  58. package/dist/src/repo/client.js.map +1 -0
  59. package/dist/src/repo/cluster-coordinator.d.ts +59 -0
  60. package/dist/src/repo/cluster-coordinator.d.ts.map +1 -0
  61. package/dist/src/repo/cluster-coordinator.js +539 -0
  62. package/dist/src/repo/cluster-coordinator.js.map +1 -0
  63. package/dist/src/repo/coordinator-repo.d.ts +29 -0
  64. package/dist/src/repo/coordinator-repo.d.ts.map +1 -0
  65. package/dist/src/repo/coordinator-repo.js +102 -0
  66. package/dist/src/repo/coordinator-repo.js.map +1 -0
  67. package/dist/src/repo/redirect.d.ts +14 -0
  68. package/dist/src/repo/redirect.d.ts.map +1 -0
  69. package/dist/src/repo/redirect.js +9 -0
  70. package/dist/src/repo/redirect.js.map +1 -0
  71. package/dist/src/repo/service.d.ts +52 -0
  72. package/dist/src/repo/service.d.ts.map +1 -0
  73. package/dist/src/repo/service.js +181 -0
  74. package/dist/src/repo/service.js.map +1 -0
  75. package/dist/src/repo/types.d.ts +7 -0
  76. package/dist/src/repo/types.d.ts.map +1 -0
  77. package/dist/src/repo/types.js +2 -0
  78. package/dist/src/repo/types.js.map +1 -0
  79. package/dist/src/routing/libp2p-known-peers.d.ts +4 -0
  80. package/dist/src/routing/libp2p-known-peers.d.ts.map +1 -0
  81. package/dist/src/routing/libp2p-known-peers.js +19 -0
  82. package/dist/src/routing/libp2p-known-peers.js.map +1 -0
  83. package/dist/src/routing/responsibility.d.ts +14 -0
  84. package/dist/src/routing/responsibility.d.ts.map +1 -0
  85. package/dist/src/routing/responsibility.js +45 -0
  86. package/dist/src/routing/responsibility.js.map +1 -0
  87. package/dist/src/routing/simple-cluster-coordinator.d.ts +23 -0
  88. package/dist/src/routing/simple-cluster-coordinator.d.ts.map +1 -0
  89. package/dist/src/routing/simple-cluster-coordinator.js +59 -0
  90. package/dist/src/routing/simple-cluster-coordinator.js.map +1 -0
  91. package/dist/src/storage/arachnode-fret-adapter.d.ts +65 -0
  92. package/dist/src/storage/arachnode-fret-adapter.d.ts.map +1 -0
  93. package/dist/src/storage/arachnode-fret-adapter.js +93 -0
  94. package/dist/src/storage/arachnode-fret-adapter.js.map +1 -0
  95. package/dist/src/storage/block-storage.d.ts +31 -0
  96. package/dist/src/storage/block-storage.d.ts.map +1 -0
  97. package/dist/src/storage/block-storage.js +154 -0
  98. package/dist/src/storage/block-storage.js.map +1 -0
  99. package/dist/src/storage/file-storage.d.ts +30 -0
  100. package/dist/src/storage/file-storage.d.ts.map +1 -0
  101. package/dist/src/storage/file-storage.js +127 -0
  102. package/dist/src/storage/file-storage.js.map +1 -0
  103. package/dist/src/storage/helpers.d.ts +3 -0
  104. package/dist/src/storage/helpers.d.ts.map +1 -0
  105. package/dist/src/storage/helpers.js +28 -0
  106. package/dist/src/storage/helpers.js.map +1 -0
  107. package/dist/src/storage/i-block-storage.d.ts +32 -0
  108. package/dist/src/storage/i-block-storage.d.ts.map +1 -0
  109. package/dist/src/storage/i-block-storage.js +2 -0
  110. package/dist/src/storage/i-block-storage.js.map +1 -0
  111. package/dist/src/storage/i-raw-storage.d.ts +20 -0
  112. package/dist/src/storage/i-raw-storage.d.ts.map +1 -0
  113. package/dist/src/storage/i-raw-storage.js +2 -0
  114. package/dist/src/storage/i-raw-storage.js.map +1 -0
  115. package/dist/src/storage/memory-storage.d.ts +27 -0
  116. package/dist/src/storage/memory-storage.d.ts.map +1 -0
  117. package/dist/src/storage/memory-storage.js +87 -0
  118. package/dist/src/storage/memory-storage.js.map +1 -0
  119. package/dist/src/storage/restoration-coordinator-v2.d.ts +63 -0
  120. package/dist/src/storage/restoration-coordinator-v2.d.ts.map +1 -0
  121. package/dist/src/storage/restoration-coordinator-v2.js +157 -0
  122. package/dist/src/storage/restoration-coordinator-v2.js.map +1 -0
  123. package/dist/src/storage/ring-selector.d.ts +56 -0
  124. package/dist/src/storage/ring-selector.d.ts.map +1 -0
  125. package/dist/src/storage/ring-selector.js +118 -0
  126. package/dist/src/storage/ring-selector.js.map +1 -0
  127. package/dist/src/storage/storage-monitor.d.ts +23 -0
  128. package/dist/src/storage/storage-monitor.d.ts.map +1 -0
  129. package/dist/src/storage/storage-monitor.js +40 -0
  130. package/dist/src/storage/storage-monitor.js.map +1 -0
  131. package/dist/src/storage/storage-repo.d.ts +17 -0
  132. package/dist/src/storage/storage-repo.d.ts.map +1 -0
  133. package/dist/src/storage/storage-repo.js +267 -0
  134. package/dist/src/storage/storage-repo.js.map +1 -0
  135. package/dist/src/storage/struct.d.ts +29 -0
  136. package/dist/src/storage/struct.d.ts.map +1 -0
  137. package/dist/src/storage/struct.js +2 -0
  138. package/dist/src/storage/struct.js.map +1 -0
  139. package/dist/src/sync/client.d.ts +27 -0
  140. package/dist/src/sync/client.d.ts.map +1 -0
  141. package/dist/src/sync/client.js +32 -0
  142. package/dist/src/sync/client.js.map +1 -0
  143. package/dist/src/sync/protocol.d.ts +58 -0
  144. package/dist/src/sync/protocol.d.ts.map +1 -0
  145. package/dist/src/sync/protocol.js +12 -0
  146. package/dist/src/sync/protocol.js.map +1 -0
  147. package/dist/src/sync/service.d.ts +62 -0
  148. package/dist/src/sync/service.d.ts.map +1 -0
  149. package/dist/src/sync/service.js +168 -0
  150. package/dist/src/sync/service.js.map +1 -0
  151. package/package.json +73 -0
  152. package/readme.md +497 -0
  153. package/src/cluster/client.ts +63 -0
  154. package/src/cluster/cluster-repo.ts +711 -0
  155. package/src/cluster/partition-detector.ts +158 -0
  156. package/src/cluster/service.ts +156 -0
  157. package/src/index.ts +30 -0
  158. package/src/it-utility.ts +36 -0
  159. package/src/libp2p-key-network.ts +334 -0
  160. package/src/libp2p-node.ts +335 -0
  161. package/src/logger.ts +9 -0
  162. package/src/network/get-network-manager.ts +17 -0
  163. package/src/network/network-manager-service.ts +334 -0
  164. package/src/peer-utils.ts +24 -0
  165. package/src/protocol-client.ts +54 -0
  166. package/src/repo/client.ts +112 -0
  167. package/src/repo/cluster-coordinator.ts +592 -0
  168. package/src/repo/coordinator-repo.ts +137 -0
  169. package/src/repo/redirect.ts +17 -0
  170. package/src/repo/service.ts +219 -0
  171. package/src/repo/types.ts +7 -0
  172. package/src/routing/libp2p-known-peers.ts +26 -0
  173. package/src/routing/responsibility.ts +63 -0
  174. package/src/routing/simple-cluster-coordinator.ts +70 -0
  175. package/src/storage/arachnode-fret-adapter.ts +128 -0
  176. package/src/storage/block-storage.ts +182 -0
  177. package/src/storage/file-storage.ts +163 -0
  178. package/src/storage/helpers.ts +29 -0
  179. package/src/storage/i-block-storage.ts +40 -0
  180. package/src/storage/i-raw-storage.ts +30 -0
  181. package/src/storage/memory-storage.ts +108 -0
  182. package/src/storage/restoration-coordinator-v2.ts +191 -0
  183. package/src/storage/ring-selector.ts +155 -0
  184. package/src/storage/storage-monitor.ts +59 -0
  185. package/src/storage/storage-repo.ts +320 -0
  186. package/src/storage/struct.ts +34 -0
  187. package/src/sync/client.ts +42 -0
  188. package/src/sync/protocol.ts +71 -0
  189. package/src/sync/service.ts +229 -0
@@ -0,0 +1,613 @@
1
+ import { blockIdsForTransforms } from "@optimystic/db-core";
2
+ import { ClusterClient } from "./client.js";
3
+ import { peerIdFromString } from "@libp2p/peer-id";
4
+ import { sha256 } from "multiformats/hashes/sha2";
5
+ import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
6
+ import { createLogger } from '../logger.js';
7
+ const log = createLogger('cluster-member');
8
+ /** State of a transaction in the cluster */
9
+ var TransactionPhase;
10
+ (function (TransactionPhase) {
11
+ TransactionPhase[TransactionPhase["Promising"] = 0] = "Promising";
12
+ TransactionPhase[TransactionPhase["OurPromiseNeeded"] = 1] = "OurPromiseNeeded";
13
+ TransactionPhase[TransactionPhase["OurCommitNeeded"] = 2] = "OurCommitNeeded";
14
+ TransactionPhase[TransactionPhase["Consensus"] = 3] = "Consensus";
15
+ TransactionPhase[TransactionPhase["Rejected"] = 4] = "Rejected";
16
+ TransactionPhase[TransactionPhase["Propagating"] = 5] = "Propagating"; // Transaction is being propagated
17
+ })(TransactionPhase || (TransactionPhase = {}));
18
+ export function clusterMember(components) {
19
+ return new ClusterMember(components.storageRepo, components.peerNetwork, components.peerId, components.protocolPrefix, components.partitionDetector, components.fretService, components.validator);
20
+ }
21
+ /**
22
+ * Handles cluster-side operations, managing promises and commits for cluster updates
23
+ * and coordinating with the local storage repo.
24
+ */
25
+ export class ClusterMember {
26
+ storageRepo;
27
+ peerNetwork;
28
+ peerId;
29
+ protocolPrefix;
30
+ partitionDetector;
31
+ fretService;
32
+ validator;
33
+ // Track active transactions by their message hash
34
+ activeTransactions = new Map();
35
+ // Queue of transactions to clean up
36
+ cleanupQueue = [];
37
+ // Serialize concurrent updates for the same transaction
38
+ pendingUpdates = new Map();
39
+ constructor(storageRepo, peerNetwork, peerId, protocolPrefix, partitionDetector, fretService, validator) {
40
+ this.storageRepo = storageRepo;
41
+ this.peerNetwork = peerNetwork;
42
+ this.peerId = peerId;
43
+ this.protocolPrefix = protocolPrefix;
44
+ this.partitionDetector = partitionDetector;
45
+ this.fretService = fretService;
46
+ this.validator = validator;
47
+ // Periodically clean up expired transactions
48
+ setInterval(() => this.queueExpiredTransactions(), 60000);
49
+ // Process cleanup queue
50
+ setInterval(() => this.processCleanupQueue(), 1000);
51
+ }
52
+ /**
53
+ * Handles an incoming cluster update, managing the two-phase commit process
54
+ * and coordinating with the local storage repo
55
+ */
56
+ async update(record) {
57
+ // Serialize concurrent updates for the same transaction
58
+ const existingUpdate = this.pendingUpdates.get(record.messageHash);
59
+ if (existingUpdate) {
60
+ log('cluster-member:concurrent-update-wait', { messageHash: record.messageHash });
61
+ await existingUpdate;
62
+ // After waiting, continue processing with the new incoming record
63
+ // to ensure proper merging of promises/commits from coordinator
64
+ }
65
+ // Create a promise for this update operation
66
+ const updatePromise = this.processUpdate(record);
67
+ this.pendingUpdates.set(record.messageHash, updatePromise);
68
+ try {
69
+ const result = await updatePromise;
70
+ return result;
71
+ }
72
+ finally {
73
+ // Remove from pending updates after a short delay to allow concurrent calls to see it
74
+ setTimeout(() => {
75
+ this.pendingUpdates.delete(record.messageHash);
76
+ }, 100);
77
+ }
78
+ }
79
+ async processUpdate(record) {
80
+ const ourId = this.peerId.toString();
81
+ const inboundPhase = record.commits[ourId] ? 'commit' : record.promises[ourId] ? 'promise' : 'initial';
82
+ log('cluster-member:incoming', {
83
+ messageHash: record.messageHash,
84
+ phase: inboundPhase,
85
+ peerCount: Object.keys(record.peers).length,
86
+ promiseCount: Object.keys(record.promises).length,
87
+ commitCount: Object.keys(record.commits).length,
88
+ existingTransaction: this.activeTransactions.has(record.messageHash)
89
+ });
90
+ // Report network size hint to FRET if provided
91
+ if (this.fretService && record.networkSizeHint && record.networkSizeConfidence) {
92
+ try {
93
+ this.fretService.reportNetworkSize(record.networkSizeHint, record.networkSizeConfidence, 'cluster');
94
+ }
95
+ catch (err) {
96
+ // Ignore errors reporting to FRET
97
+ }
98
+ }
99
+ // Validate the incoming record
100
+ await this.validateRecord(record);
101
+ const existingState = this.activeTransactions.get(record.messageHash);
102
+ let currentRecord = existingState?.record || record;
103
+ if (existingState) {
104
+ log('cluster-member:merge-start', {
105
+ messageHash: record.messageHash,
106
+ existingPromises: Object.keys(existingState.record.promises ?? {}),
107
+ existingCommits: Object.keys(existingState.record.commits ?? {}),
108
+ incomingPromises: Object.keys(record.promises ?? {}),
109
+ incomingCommits: Object.keys(record.commits ?? {})
110
+ });
111
+ }
112
+ // If we have an existing record, merge the signatures
113
+ if (existingState) {
114
+ currentRecord = await this.mergeRecords(existingState.record, record);
115
+ log('cluster-member:merge-complete', {
116
+ messageHash: record.messageHash,
117
+ mergedPromises: Object.keys(currentRecord.promises ?? {}),
118
+ mergedCommits: Object.keys(currentRecord.commits ?? {})
119
+ });
120
+ }
121
+ // Get the current transaction state
122
+ const phase = await this.getTransactionPhase(currentRecord);
123
+ log('cluster-member:phase', {
124
+ messageHash: record.messageHash,
125
+ phase,
126
+ promises: Object.keys(currentRecord.promises ?? {}),
127
+ commits: Object.keys(currentRecord.commits ?? {})
128
+ });
129
+ let shouldPersist = true;
130
+ // Handle the transaction based on its state
131
+ switch (phase) {
132
+ case TransactionPhase.OurPromiseNeeded:
133
+ log('cluster-member:action-promise', {
134
+ messageHash: record.messageHash
135
+ });
136
+ currentRecord = await this.handlePromiseNeeded(currentRecord);
137
+ log('cluster-member:action-promise-complete', {
138
+ messageHash: record.messageHash,
139
+ promises: Object.keys(currentRecord.promises ?? {})
140
+ });
141
+ break;
142
+ case TransactionPhase.OurCommitNeeded:
143
+ log('cluster-member:action-commit', {
144
+ messageHash: record.messageHash
145
+ });
146
+ currentRecord = await this.handleCommitNeeded(currentRecord);
147
+ log('cluster-member:action-commit-complete', {
148
+ messageHash: record.messageHash,
149
+ commits: Object.keys(currentRecord.commits ?? {})
150
+ });
151
+ // After adding our commit, clear the transaction - the coordinator will handle consensus
152
+ shouldPersist = false;
153
+ break;
154
+ case TransactionPhase.Consensus:
155
+ log('cluster-member:action-consensus', {
156
+ messageHash: record.messageHash
157
+ });
158
+ await this.handleConsensus(currentRecord);
159
+ // Don't call clearTransaction here - it happens in handleConsensus
160
+ shouldPersist = false;
161
+ break;
162
+ case TransactionPhase.Rejected:
163
+ log('cluster-member:action-rejected', {
164
+ messageHash: record.messageHash
165
+ });
166
+ // Don't call clearTransaction here - it happens in handleRejection
167
+ await this.handleRejection(currentRecord);
168
+ shouldPersist = false;
169
+ break;
170
+ case TransactionPhase.Propagating:
171
+ // Transaction is complete and propagating - clean it up
172
+ log('cluster-member:phase-propagating', {
173
+ messageHash: record.messageHash
174
+ });
175
+ shouldPersist = false;
176
+ break;
177
+ case TransactionPhase.Promising:
178
+ // Still collecting promises from peers - if we haven't added ours and there's no conflict, add it
179
+ // This state shouldn't normally be reached since OurPromiseNeeded is checked first
180
+ log('cluster-member:phase-promising-blocked', {
181
+ messageHash: record.messageHash
182
+ });
183
+ break;
184
+ }
185
+ if (shouldPersist) {
186
+ // Update transaction state
187
+ const timeouts = this.setupTimeouts(currentRecord);
188
+ this.activeTransactions.set(record.messageHash, {
189
+ record: currentRecord,
190
+ lastUpdate: Date.now(),
191
+ promiseTimeout: timeouts.promiseTimeout,
192
+ resolutionTimeout: timeouts.resolutionTimeout
193
+ });
194
+ log('cluster-member:state-persist', {
195
+ messageHash: record.messageHash,
196
+ storedPromises: Object.keys(currentRecord.promises ?? {}),
197
+ storedCommits: Object.keys(currentRecord.commits ?? {})
198
+ });
199
+ }
200
+ else {
201
+ log('cluster-member:state-clear', {
202
+ messageHash: record.messageHash
203
+ });
204
+ this.clearTransaction(record.messageHash);
205
+ }
206
+ // Skip propagation - the coordinator manages distribution
207
+ // await this.propagateIfNeeded(currentRecord);
208
+ log('cluster-member:update-complete', {
209
+ messageHash: record.messageHash,
210
+ promiseCount: Object.keys(currentRecord.promises).length,
211
+ commitCount: Object.keys(currentRecord.commits).length
212
+ });
213
+ return currentRecord;
214
+ }
215
+ /**
216
+ * Merges two records, validating that non-signature fields match
217
+ */
218
+ async mergeRecords(existing, incoming) {
219
+ log('cluster-member:merge-records', {
220
+ messageHash: existing.messageHash,
221
+ existingPromises: Object.keys(existing.promises ?? {}),
222
+ existingCommits: Object.keys(existing.commits ?? {}),
223
+ incomingPromises: Object.keys(incoming.promises ?? {}),
224
+ incomingCommits: Object.keys(incoming.commits ?? {})
225
+ });
226
+ // Verify that immutable fields match
227
+ if (existing.messageHash !== incoming.messageHash) {
228
+ throw new Error('Message hash mismatch');
229
+ }
230
+ if (JSON.stringify(existing.message) !== JSON.stringify(incoming.message)) {
231
+ throw new Error('Message content mismatch');
232
+ }
233
+ if (JSON.stringify(existing.peers) !== JSON.stringify(incoming.peers)) {
234
+ throw new Error('Peers mismatch');
235
+ }
236
+ // Merge signatures, keeping the most recent valid ones
237
+ return {
238
+ ...existing,
239
+ promises: { ...existing.promises, ...incoming.promises },
240
+ commits: { ...existing.commits, ...incoming.commits }
241
+ };
242
+ }
243
+ async validateRecord(record) {
244
+ // TODO: Fix hash validation logic to match coordinator's hash generation
245
+ // The coordinator creates the hash from the message, but this tries to re-hash the hash itself
246
+ // Validate signatures
247
+ await this.validateSignatures(record);
248
+ // Validate expiration
249
+ if (record.message.expiration && record.message.expiration < Date.now()) {
250
+ throw new Error('Transaction expired');
251
+ }
252
+ }
253
+ async computeMessageHash(record) {
254
+ const msgBytes = new TextEncoder().encode(record.messageHash + JSON.stringify(record.message));
255
+ const hashBytes = await sha256.digest(msgBytes);
256
+ return uint8ArrayToString(hashBytes.digest, 'base64url');
257
+ }
258
+ async validateSignatures(record) {
259
+ // Validate promise signatures
260
+ const promiseHash = await this.computePromiseHash(record);
261
+ for (const [peerId, signature] of Object.entries(record.promises)) {
262
+ if (!await this.verifySignature(peerId, promiseHash, signature)) {
263
+ throw new Error(`Invalid promise signature from ${peerId}`);
264
+ }
265
+ }
266
+ // Validate commit signatures
267
+ const commitHash = await this.computeCommitHash(record);
268
+ for (const [peerId, signature] of Object.entries(record.commits)) {
269
+ if (!await this.verifySignature(peerId, commitHash, signature)) {
270
+ throw new Error(`Invalid commit signature from ${peerId}`);
271
+ }
272
+ }
273
+ }
274
+ async computePromiseHash(record) {
275
+ const msgBytes = new TextEncoder().encode(record.messageHash + JSON.stringify(record.message));
276
+ const hashBytes = await sha256.digest(msgBytes);
277
+ return uint8ArrayToString(hashBytes.digest, 'base64url');
278
+ }
279
+ async computeCommitHash(record) {
280
+ const msgBytes = new TextEncoder().encode(record.messageHash + JSON.stringify(record.message) + JSON.stringify(record.promises));
281
+ const hashBytes = await sha256.digest(msgBytes);
282
+ return uint8ArrayToString(hashBytes.digest, 'base64url');
283
+ }
284
+ async verifySignature(peerId, hash, signature) {
285
+ // TODO: Implement actual signature verification
286
+ return true;
287
+ }
288
+ async getTransactionPhase(record) {
289
+ const peerCount = Object.keys(record.peers).length;
290
+ const promiseCount = Object.keys(record.promises).length;
291
+ const commitCount = Object.keys(record.commits).length;
292
+ const ourId = this.peerId.toString();
293
+ // Check for rejections
294
+ const rejectedPromises = Object.values(record.promises).filter(s => s.type === 'reject');
295
+ const rejectedCommits = Object.values(record.commits).filter(s => s.type === 'reject');
296
+ if (rejectedPromises.length > 0 || this.hasMajority(rejectedCommits.length, peerCount)) {
297
+ return TransactionPhase.Rejected;
298
+ }
299
+ // Check if we need to promise
300
+ if (!record.promises[ourId] && !this.hasConflict(record)) {
301
+ return TransactionPhase.OurPromiseNeeded;
302
+ }
303
+ // Check if still collecting promises
304
+ if (promiseCount < peerCount) {
305
+ return TransactionPhase.Promising;
306
+ }
307
+ // Check if we need to commit
308
+ if (promiseCount === peerCount && !record.commits[ourId]) {
309
+ return TransactionPhase.OurCommitNeeded;
310
+ }
311
+ // Check for consensus
312
+ const approvedCommits = Object.values(record.commits).filter(s => s.type === 'approve');
313
+ if (this.hasMajority(approvedCommits.length, peerCount)) {
314
+ return TransactionPhase.Consensus;
315
+ }
316
+ return TransactionPhase.Propagating;
317
+ }
318
+ hasMajority(count, total) {
319
+ return count > total / 2;
320
+ }
321
+ async handlePromiseNeeded(record) {
322
+ // Validate pend operations if we have a validator
323
+ const validationResult = await this.validatePendOperations(record);
324
+ const signature = validationResult.valid
325
+ ? { type: 'approve', signature: 'approved' }
326
+ : { type: 'reject', signature: 'rejected', rejectReason: validationResult.reason };
327
+ if (!validationResult.valid) {
328
+ log('cluster-member:validation-rejected', {
329
+ messageHash: record.messageHash,
330
+ reason: validationResult.reason
331
+ });
332
+ }
333
+ return {
334
+ ...record,
335
+ promises: {
336
+ ...record.promises,
337
+ [this.peerId.toString()]: signature
338
+ }
339
+ };
340
+ }
341
+ /**
342
+ * Validates pend operations in a cluster record using the transaction validator.
343
+ * Returns success if no validator is configured (backwards compatibility).
344
+ */
345
+ async validatePendOperations(record) {
346
+ if (!this.validator) {
347
+ return { valid: true };
348
+ }
349
+ // Find pend operations in the message
350
+ for (const operation of record.message.operations) {
351
+ if ('pend' in operation) {
352
+ const pendRequest = operation.pend;
353
+ // Only validate if we have a transaction and operationsHash
354
+ if (pendRequest.transaction && pendRequest.operationsHash) {
355
+ const result = await this.validator.validate(pendRequest.transaction, pendRequest.operationsHash);
356
+ if (!result.valid) {
357
+ return { valid: false, reason: result.reason };
358
+ }
359
+ }
360
+ }
361
+ }
362
+ return { valid: true };
363
+ }
364
+ async handleCommitNeeded(record) {
365
+ if (this.hasLocalCommit(record)) {
366
+ return record;
367
+ }
368
+ const signature = {
369
+ type: 'approve',
370
+ signature: 'committed' // TODO: Actually sign the commit hash
371
+ };
372
+ return {
373
+ ...record,
374
+ commits: {
375
+ ...record.commits,
376
+ [this.peerId.toString()]: signature
377
+ }
378
+ };
379
+ }
380
+ async handleConsensus(record) {
381
+ // Execute the operations only if we haven't already
382
+ const state = this.activeTransactions.get(record.messageHash);
383
+ if (!this.hasLocalCommit(state?.record ?? record)) {
384
+ for (const operation of record.message.operations) {
385
+ if ('get' in operation) {
386
+ await this.storageRepo.get(operation.get);
387
+ }
388
+ else if ('pend' in operation) {
389
+ await this.storageRepo.pend(operation.pend);
390
+ }
391
+ else if ('commit' in operation) {
392
+ await this.storageRepo.commit(operation.commit);
393
+ }
394
+ else if ('cancel' in operation) {
395
+ await this.storageRepo.cancel(operation.cancel.actionRef);
396
+ }
397
+ }
398
+ }
399
+ // Don't clear here - will be cleared by shouldPersist = false in the main flow
400
+ }
401
+ async handleRejection(record) {
402
+ // Clean up any resources - will be cleared by shouldPersist = false in the main flow
403
+ }
404
+ setupTimeouts(record) {
405
+ if (!record.message.expiration) {
406
+ return {};
407
+ }
408
+ return {
409
+ promiseTimeout: setTimeout(() => this.handleExpiration(record.messageHash), record.message.expiration - Date.now()),
410
+ resolutionTimeout: setTimeout(() => this.resolveWithPeers(record.messageHash), record.message.expiration + 5000 - Date.now())
411
+ };
412
+ }
413
+ hasConflict(record) {
414
+ const now = Date.now();
415
+ const staleThresholdMs = 2000; // 2 seconds - allow more time for distributed consensus
416
+ for (const [existingHash, state] of Array.from(this.activeTransactions.entries())) {
417
+ if (existingHash === record.messageHash) {
418
+ continue;
419
+ }
420
+ // Clean up stale transactions that have been around too long
421
+ if (now - state.lastUpdate > staleThresholdMs) {
422
+ log('cluster-member:stale-cleanup', {
423
+ messageHash: existingHash,
424
+ age: now - state.lastUpdate
425
+ });
426
+ this.clearTransaction(existingHash);
427
+ continue;
428
+ }
429
+ if (this.operationsConflict(state.record.message.operations, record.message.operations)) {
430
+ // Use race resolution to determine winner
431
+ const resolution = this.resolveRace(state.record, record);
432
+ if (resolution === 'keep-existing') {
433
+ log('cluster-member:race-keep-existing', {
434
+ existing: existingHash,
435
+ incoming: record.messageHash
436
+ });
437
+ return true; // Reject incoming
438
+ }
439
+ else {
440
+ // Accept incoming, abort existing
441
+ log('cluster-member:race-accept-incoming', {
442
+ existing: existingHash,
443
+ incoming: record.messageHash
444
+ });
445
+ this.clearTransaction(existingHash);
446
+ continue; // Check other conflicts
447
+ }
448
+ }
449
+ }
450
+ return false; // No blocking conflicts
451
+ }
452
+ /**
453
+ * Resolve race between two conflicting transactions.
454
+ * Transaction with more promises wins. If tied, higher hash wins.
455
+ */
456
+ resolveRace(existing, incoming) {
457
+ const existingCount = Object.keys(existing.promises).length;
458
+ const incomingCount = Object.keys(incoming.promises).length;
459
+ // Transaction with more promises wins
460
+ if (existingCount > incomingCount) {
461
+ return 'keep-existing';
462
+ }
463
+ if (incomingCount > existingCount) {
464
+ return 'accept-incoming';
465
+ }
466
+ // Tie-breaker: higher message hash wins (deterministic)
467
+ return existing.messageHash > incoming.messageHash ? 'keep-existing' : 'accept-incoming';
468
+ }
469
+ operationsConflict(ops1, ops2) {
470
+ // Check if one is a commit for the same action as a pend - these don't conflict
471
+ const actionId1 = this.getActionId(ops1);
472
+ const actionId2 = this.getActionId(ops2);
473
+ if (actionId1 && actionId2 && actionId1 === actionId2) {
474
+ // Same action - commit is resolving the pend, not conflicting
475
+ return false;
476
+ }
477
+ const blocks1 = new Set(this.getAffectedBlockIds(ops1));
478
+ const blocks2 = new Set(this.getAffectedBlockIds(ops2));
479
+ for (const block of Array.from(blocks1)) {
480
+ if (blocks2.has(block)) {
481
+ log('cluster-member:conflict-detected', {
482
+ blocks1: Array.from(blocks1),
483
+ blocks2: Array.from(blocks2),
484
+ conflictingBlock: block
485
+ });
486
+ return true;
487
+ }
488
+ }
489
+ return false;
490
+ }
491
+ getActionId(operations) {
492
+ for (const operation of operations) {
493
+ if ('pend' in operation) {
494
+ return operation.pend.actionId;
495
+ }
496
+ else if ('commit' in operation) {
497
+ return operation.commit.actionId;
498
+ }
499
+ else if ('cancel' in operation) {
500
+ return operation.cancel.actionRef.actionId;
501
+ }
502
+ }
503
+ return undefined;
504
+ }
505
+ getAffectedBlockIds(operations) {
506
+ const blockIds = new Set();
507
+ for (const operation of operations) {
508
+ if ('get' in operation) {
509
+ operation.get.blockIds.forEach(id => blockIds.add(id));
510
+ }
511
+ else if ('pend' in operation) {
512
+ // Use blockIdsForTransforms to correctly extract block IDs from Transforms structure
513
+ blockIdsForTransforms(operation.pend.transforms).forEach(id => blockIds.add(id));
514
+ }
515
+ else if ('commit' in operation) {
516
+ operation.commit.blockIds.forEach(id => blockIds.add(id));
517
+ }
518
+ else if ('cancel' in operation) {
519
+ operation.cancel.actionRef.blockIds.forEach(id => blockIds.add(id));
520
+ }
521
+ }
522
+ return Array.from(blockIds);
523
+ }
524
+ async propagateIfNeeded(record) {
525
+ const promises = [];
526
+ for (const [peerId, peer] of Object.entries(record.peers)) {
527
+ if (peerId === this.peerId.toString())
528
+ continue;
529
+ try {
530
+ const client = ClusterClient.create(peerIdFromString(peerId), this.peerNetwork, this.protocolPrefix);
531
+ promises.push(client.update(record));
532
+ }
533
+ catch (error) {
534
+ console.error(`Failed to propagate to peer ${peerId}:`, error);
535
+ }
536
+ }
537
+ await Promise.allSettled(promises);
538
+ }
539
+ async handleExpiration(messageHash) {
540
+ const state = this.activeTransactions.get(messageHash);
541
+ if (!state)
542
+ return;
543
+ if (!state.record.promises[this.peerId.toString()]) {
544
+ const signature = {
545
+ type: 'reject',
546
+ signature: 'rejected',
547
+ rejectReason: 'Transaction expired'
548
+ };
549
+ const updatedRecord = {
550
+ ...state.record,
551
+ promises: {
552
+ ...state.record.promises,
553
+ [this.peerId.toString()]: signature
554
+ }
555
+ };
556
+ this.activeTransactions.set(messageHash, {
557
+ ...state,
558
+ record: updatedRecord
559
+ });
560
+ await this.propagateIfNeeded(updatedRecord);
561
+ }
562
+ }
563
+ async resolveWithPeers(messageHash) {
564
+ // This method is disabled - the coordinator handles all retry logic
565
+ // Keeping the skeleton in case we need peer-initiated recovery in the future
566
+ log('cluster-member:resolve-skipped', { messageHash, reason: 'coordinator-handles-retry' });
567
+ }
568
+ queueExpiredTransactions() {
569
+ const now = Date.now();
570
+ for (const [messageHash, state] of Array.from(this.activeTransactions.entries())) {
571
+ if (state.record.message.expiration && state.record.message.expiration < now) {
572
+ this.cleanupQueue.push(messageHash);
573
+ }
574
+ }
575
+ }
576
+ async processCleanupQueue() {
577
+ while (this.cleanupQueue.length > 0) {
578
+ const messageHash = this.cleanupQueue.shift();
579
+ if (!messageHash)
580
+ continue;
581
+ const state = this.activeTransactions.get(messageHash);
582
+ if (!state)
583
+ continue;
584
+ const phase = await this.getTransactionPhase(state.record);
585
+ if (phase !== TransactionPhase.Consensus && phase !== TransactionPhase.Rejected) {
586
+ this.activeTransactions.delete(messageHash);
587
+ }
588
+ }
589
+ }
590
+ hasLocalCommit(record) {
591
+ const ourId = this.peerId.toString();
592
+ return Boolean(record.commits[ourId]);
593
+ }
594
+ clearTransaction(messageHash) {
595
+ const state = this.activeTransactions.get(messageHash);
596
+ if (!state) {
597
+ log('cluster-member:clear-miss', { messageHash });
598
+ return;
599
+ }
600
+ if (state.promiseTimeout) {
601
+ clearTimeout(state.promiseTimeout);
602
+ }
603
+ if (state.resolutionTimeout) {
604
+ clearTimeout(state.resolutionTimeout);
605
+ }
606
+ this.activeTransactions.delete(messageHash);
607
+ log('cluster-member:clear-done', {
608
+ messageHash,
609
+ remaining: Array.from(this.activeTransactions.keys())
610
+ });
611
+ }
612
+ }
613
+ //# sourceMappingURL=cluster-repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-repo.js","sourceRoot":"","sources":["../../../src/cluster/cluster-repo.ts"],"names":[],"mappings":"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"}