@optimystic/db-p2p 0.24.2 → 0.25.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.
- package/{readme.md → README.md} +688 -668
- package/dist/src/cluster/block-transfer-service.d.ts +133 -10
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +155 -9
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/block-transfer.d.ts +67 -7
- package/dist/src/cluster/block-transfer.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer.js +127 -24
- package/dist/src/cluster/block-transfer.js.map +1 -1
- package/dist/src/cluster/certified-claims.d.ts +170 -0
- package/dist/src/cluster/certified-claims.d.ts.map +1 -0
- package/dist/src/cluster/certified-claims.js +200 -0
- package/dist/src/cluster/certified-claims.js.map +1 -0
- package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
- package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
- package/dist/src/cluster/client-signature-verifier.js +33 -0
- package/dist/src/cluster/client-signature-verifier.js.map +1 -0
- package/dist/src/cluster/cluster-policy.d.ts +9 -3
- package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
- package/dist/src/cluster/cluster-policy.js +111 -27
- package/dist/src/cluster/cluster-policy.js.map +1 -1
- package/dist/src/cluster/cluster-repo.d.ts +140 -11
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +485 -29
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-proof.d.ts +134 -0
- package/dist/src/cluster/commit-proof.d.ts.map +1 -0
- package/dist/src/cluster/commit-proof.js +263 -0
- package/dist/src/cluster/commit-proof.js.map +1 -0
- package/dist/src/cluster/quorum-restore.d.ts +95 -8
- package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
- package/dist/src/cluster/quorum-restore.js +113 -14
- package/dist/src/cluster/quorum-restore.js.map +1 -1
- package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
- package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
- package/dist/src/cluster/rebalance-monitor.js +207 -5
- package/dist/src/cluster/rebalance-monitor.js.map +1 -1
- package/dist/src/cluster/reconcile-block.d.ts +27 -7
- package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
- package/dist/src/cluster/reconcile-block.js +179 -38
- package/dist/src/cluster/reconcile-block.js.map +1 -1
- package/dist/src/cluster/service.d.ts +13 -4
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +17 -18
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +8 -2
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +7 -7
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/host.d.ts.map +1 -1
- package/dist/src/cohort-topic/host.js +8 -7
- package/dist/src/cohort-topic/host.js.map +1 -1
- package/dist/src/cohort-topic/stream-util.d.ts +7 -6
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
- package/dist/src/cohort-topic/stream-util.js +14 -41
- package/dist/src/cohort-topic/stream-util.js.map +1 -1
- package/dist/src/dispute/cascade.d.ts +7 -8
- package/dist/src/dispute/cascade.d.ts.map +1 -1
- package/dist/src/dispute/cascade.js +24 -7
- package/dist/src/dispute/cascade.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +5 -0
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +13 -3
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +33 -15
- package/dist/src/dispute/invalidation.d.ts.map +1 -1
- package/dist/src/dispute/invalidation.js +127 -34
- package/dist/src/dispute/invalidation.js.map +1 -1
- package/dist/src/dispute/service.d.ts.map +1 -1
- package/dist/src/dispute/service.js +2 -1
- package/dist/src/dispute/service.js.map +1 -1
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +14 -10
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +28 -58
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +38 -7
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +148 -63
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/network/open-protocol-stream.d.ts +56 -0
- package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
- package/dist/src/network/open-protocol-stream.js +60 -0
- package/dist/src/network/open-protocol-stream.js.map +1 -0
- package/dist/src/network/register-protocol-handler.d.ts +66 -0
- package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
- package/dist/src/network/register-protocol-handler.js +51 -0
- package/dist/src/network/register-protocol-handler.js.map +1 -0
- package/dist/src/peer-address-book.d.ts +60 -2
- package/dist/src/peer-address-book.d.ts.map +1 -1
- package/dist/src/peer-address-book.js +89 -1
- package/dist/src/peer-address-book.js.map +1 -1
- package/dist/src/pend-validation.d.ts +65 -0
- package/dist/src/pend-validation.d.ts.map +1 -0
- package/dist/src/pend-validation.js +69 -0
- package/dist/src/pend-validation.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
- package/dist/src/reactivity/notify-transport.js +2 -1
- package/dist/src/reactivity/notify-transport.js.map +1 -1
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
- package/dist/src/reactivity/push-state-gossip.js +2 -1
- package/dist/src/reactivity/push-state-gossip.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +32 -6
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +44 -10
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +181 -25
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +650 -62
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/served-repo-proxy.d.ts +30 -0
- package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
- package/dist/src/repo/served-repo-proxy.js +50 -0
- package/dist/src/repo/served-repo-proxy.js.map +1 -0
- package/dist/src/repo/service.d.ts +16 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +18 -16
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/reputation/types.d.ts +3 -1
- package/dist/src/reputation/types.d.ts.map +1 -1
- package/dist/src/reputation/types.js +3 -1
- package/dist/src/reputation/types.js.map +1 -1
- package/dist/src/rn.d.ts +24 -2
- package/dist/src/rn.d.ts.map +1 -1
- package/dist/src/rn.js +33 -4
- package/dist/src/rn.js.map +1 -1
- package/dist/src/storage/block-archive.d.ts +153 -0
- package/dist/src/storage/block-archive.d.ts.map +1 -0
- package/dist/src/storage/block-archive.js +194 -0
- package/dist/src/storage/block-archive.js.map +1 -0
- package/dist/src/storage/block-latch.d.ts +92 -0
- package/dist/src/storage/block-latch.d.ts.map +1 -0
- package/dist/src/storage/block-latch.js +132 -0
- package/dist/src/storage/block-latch.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +169 -12
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +415 -152
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/cached-raw-storage.d.ts +5 -1
- package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/cached-raw-storage.js +16 -1
- package/dist/src/storage/cached-raw-storage.js.map +1 -1
- package/dist/src/storage/cached-store-driver.d.ts +14 -4
- package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
- package/dist/src/storage/cached-store-driver.js +39 -5
- package/dist/src/storage/cached-store-driver.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +70 -19
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/i-block-storage.js +21 -1
- package/dist/src/storage/i-block-storage.js.map +1 -1
- package/dist/src/storage/i-raw-storage.d.ts +38 -0
- package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.d.ts +14 -8
- package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.js +29 -9
- package/dist/src/storage/kv-raw-storage.js.map +1 -1
- package/dist/src/storage/memory-store-driver.d.ts +4 -1
- package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
- package/dist/src/storage/memory-store-driver.js +22 -2
- package/dist/src/storage/memory-store-driver.js.map +1 -1
- package/dist/src/storage/raw-store-codec.js +2 -2
- package/dist/src/storage/raw-store-driver.d.ts +44 -3
- package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.d.ts +60 -3
- package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.js +68 -4
- package/dist/src/storage/shared-cache-pool.js.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +204 -26
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +422 -119
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/storage/store-identity.d.ts +21 -0
- package/dist/src/storage/store-identity.d.ts.map +1 -0
- package/dist/src/storage/store-identity.js +33 -0
- package/dist/src/storage/store-identity.js.map +1 -0
- package/dist/src/storage/struct.d.ts +15 -0
- package/dist/src/storage/struct.d.ts.map +1 -1
- package/dist/src/storage/with-read-cache.d.ts +92 -0
- package/dist/src/storage/with-read-cache.d.ts.map +1 -0
- package/dist/src/storage/with-read-cache.js +132 -0
- package/dist/src/storage/with-read-cache.js.map +1 -0
- package/dist/src/sync/service.d.ts +13 -3
- package/dist/src/sync/service.d.ts.map +1 -1
- package/dist/src/sync/service.js +7 -30
- package/dist/src/sync/service.js.map +1 -1
- package/dist/src/testing/mesh-harness.d.ts +75 -2
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +193 -81
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
- package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
- package/dist/src/testing/raw-storage-conformance.js +97 -2
- package/dist/src/testing/raw-storage-conformance.js.map +1 -1
- package/package.json +5 -6
- package/src/cluster/block-transfer-service.ts +528 -312
- package/src/cluster/block-transfer.ts +547 -424
- package/src/cluster/certified-claims.ts +319 -0
- package/src/cluster/client-signature-verifier.ts +34 -0
- package/src/cluster/cluster-policy.ts +294 -203
- package/src/cluster/cluster-repo.ts +2501 -2034
- package/src/cluster/commit-proof.ts +344 -0
- package/src/cluster/quorum-restore.ts +348 -223
- package/src/cluster/rebalance-monitor.ts +539 -254
- package/src/cluster/reconcile-block.ts +404 -203
- package/src/cluster/service.ts +23 -20
- package/src/cluster/spread-on-churn.ts +352 -346
- package/src/cohort-topic/host.ts +8 -7
- package/src/cohort-topic/stream-util.ts +14 -43
- package/src/dispute/cascade.ts +31 -15
- package/src/dispute/dispute-service.ts +706 -696
- package/src/dispute/invalidation.ts +162 -52
- package/src/dispute/service.ts +126 -125
- package/src/index.ts +7 -0
- package/src/libp2p-key-network.ts +1204 -1235
- package/src/libp2p-node-base.ts +185 -70
- package/src/network/open-protocol-stream.ts +87 -0
- package/src/network/register-protocol-handler.ts +85 -0
- package/src/peer-address-book.ts +96 -2
- package/src/pend-validation.ts +89 -0
- package/src/reactivity/notify-transport.ts +2 -1
- package/src/reactivity/push-state-gossip.ts +2 -1
- package/src/repo/cluster-coordinator.ts +65 -11
- package/src/repo/coordinator-repo.ts +729 -71
- package/src/repo/served-repo-proxy.ts +55 -0
- package/src/repo/service.ts +25 -16
- package/src/reputation/types.ts +3 -1
- package/src/rn.ts +34 -4
- package/src/storage/block-archive.ts +242 -0
- package/src/storage/block-latch.ts +144 -0
- package/src/storage/block-storage.ts +787 -498
- package/src/storage/cached-raw-storage.ts +21 -1
- package/src/storage/cached-store-driver.ts +898 -859
- package/src/storage/i-block-storage.ts +172 -116
- package/src/storage/i-raw-storage.ts +40 -0
- package/src/storage/kv-raw-storage.ts +34 -9
- package/src/storage/memory-store-driver.ts +26 -2
- package/src/storage/raw-store-codec.ts +42 -42
- package/src/storage/raw-store-driver.ts +45 -3
- package/src/storage/shared-cache-pool.ts +516 -452
- package/src/storage/storage-repo.ts +1421 -1014
- package/src/storage/store-identity.ts +41 -0
- package/src/storage/struct.ts +52 -34
- package/src/storage/with-read-cache.ts +182 -0
- package/src/sync/service.ts +178 -198
- package/src/testing/mesh-harness.ts +524 -344
- package/src/testing/raw-storage-conformance.ts +114 -2
package/src/sync/service.ts
CHANGED
|
@@ -1,198 +1,178 @@
|
|
|
1
|
-
import type { ComponentLogger, Connection, Startable } from '@libp2p/interface';
|
|
2
|
-
import type
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import type
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
request.
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
range: [latest.rev, latest.rev + 1]
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
return archive;
|
|
185
|
-
} catch (error) {
|
|
186
|
-
this.log.error('Error building archive for block %s:', blockId, error);
|
|
187
|
-
return undefined;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Factory function for creating a SyncService.
|
|
194
|
-
* Follows the libp2p service pattern.
|
|
195
|
-
*/
|
|
196
|
-
export const syncService = (init: SyncServiceInit = {}) =>
|
|
197
|
-
(components: SyncServiceComponents) => new SyncService(components, init);
|
|
198
|
-
|
|
1
|
+
import type { ComponentLogger, Connection, Startable } from '@libp2p/interface';
|
|
2
|
+
import { buildSyncProtocol, type SyncRequest, type SyncResponse } from './protocol.js';
|
|
3
|
+
import { pipe } from 'it-pipe';
|
|
4
|
+
import { toString as u8ToString } from 'uint8arrays/to-string';
|
|
5
|
+
import * as lp from 'it-length-prefixed';
|
|
6
|
+
import { MAX_CONTROL_MESSAGE_BYTES } from '../protocol-limits.js';
|
|
7
|
+
import type { Uint8ArrayList } from 'uint8arraylist';
|
|
8
|
+
import { createInboundStreamAuthorization, type InboundStreamAuthorization, type InboundStreamAuthorizationInit } from '../inbound-authorization.js';
|
|
9
|
+
import { serveBlockArchive, type ArchiveServingRepo } from '../storage/block-archive.js';
|
|
10
|
+
import { registerProtocolHandler } from '../network/register-protocol-handler.js';
|
|
11
|
+
import type { BlockArchive } from '../storage/struct.js';
|
|
12
|
+
|
|
13
|
+
export interface SyncServiceInit extends InboundStreamAuthorizationInit {
|
|
14
|
+
protocolPrefix?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SyncServiceComponents {
|
|
18
|
+
logger: ComponentLogger;
|
|
19
|
+
registrar: { handle: (...args: any[]) => Promise<void>, unhandle: (...args: any[]) => Promise<void> };
|
|
20
|
+
/**
|
|
21
|
+
* The local store this node answers repair fetches out of. Declared as `ArchiveServingRepo`
|
|
22
|
+
* rather than bare `IRepo` so the seam SAYS that the served archive's commit proof is read off
|
|
23
|
+
* this object: a wiring that hands over a delegating proxy without the accessor serves every
|
|
24
|
+
* archive proof-less, which is invisible to any test that reads a real `StorageRepo` directly.
|
|
25
|
+
* The accessor stays optional — a plain `IRepo` embedder serves the pre-proof archive, which
|
|
26
|
+
* every consumer still handles.
|
|
27
|
+
*/
|
|
28
|
+
repo: ArchiveServingRepo;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type Logger = ReturnType<ComponentLogger['forComponent']>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Service for handling incoming sync requests from other cluster peers.
|
|
35
|
+
*
|
|
36
|
+
* Listens on the sync protocol and responds to block requests by:
|
|
37
|
+
* 1. Extracting the block from local storage
|
|
38
|
+
* 2. Building a BlockArchive with requested revisions
|
|
39
|
+
* 3. Sending the response back to the requester
|
|
40
|
+
*
|
|
41
|
+
* This is the server-side of the block restoration mechanism.
|
|
42
|
+
*/
|
|
43
|
+
export class SyncService implements Startable {
|
|
44
|
+
private running = false;
|
|
45
|
+
private readonly log: Logger;
|
|
46
|
+
private readonly protocol: string;
|
|
47
|
+
private readonly repo: ArchiveServingRepo;
|
|
48
|
+
private readonly registrar: { handle: (...args: any[]) => Promise<void>, unhandle: (...args: any[]) => Promise<void> };
|
|
49
|
+
/** Optional embedder authorization gate; `undefined` (the default) means no check runs. */
|
|
50
|
+
private readonly authorization: InboundStreamAuthorization | undefined;
|
|
51
|
+
|
|
52
|
+
constructor(
|
|
53
|
+
components: SyncServiceComponents,
|
|
54
|
+
init: SyncServiceInit = {}
|
|
55
|
+
) {
|
|
56
|
+
this.log = components.logger.forComponent('db-p2p:sync-service');
|
|
57
|
+
this.protocol = buildSyncProtocol(init.protocolPrefix ?? '');
|
|
58
|
+
this.repo = components.repo;
|
|
59
|
+
this.registrar = components.registrar;
|
|
60
|
+
this.authorization = createInboundStreamAuthorization(init, this.protocol, (msg, ...args) => this.log.error(msg, ...args));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async start(): Promise<void> {
|
|
64
|
+
if (this.running) return;
|
|
65
|
+
|
|
66
|
+
await registerProtocolHandler(this.registrar, this.protocol, this.handleSyncRequest.bind(this));
|
|
67
|
+
|
|
68
|
+
this.running = true;
|
|
69
|
+
this.log('Sync service started on protocol %s', this.protocol);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async stop(): Promise<void> {
|
|
73
|
+
if (!this.running) return;
|
|
74
|
+
await this.registrar.unhandle(this.protocol);
|
|
75
|
+
this.running = false;
|
|
76
|
+
this.log('Sync service stopped');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Handle an incoming sync request stream.
|
|
81
|
+
* Uses a streaming pipeline (like the repo service) to process the
|
|
82
|
+
* request and yield a response immediately — avoids a read/write deadlock.
|
|
83
|
+
*/
|
|
84
|
+
private handleSyncRequest(stream: any, connection?: Connection): void {
|
|
85
|
+
const self = this;
|
|
86
|
+
// The registrar handler receives the stream (or, in an older shape, a `{ stream }`
|
|
87
|
+
// wrapper) directly; resolve it once so the authorization abort, the pipeline and the
|
|
88
|
+
// error path all act on the same object.
|
|
89
|
+
const actualStream = stream.stream ?? stream;
|
|
90
|
+
void (async () => {
|
|
91
|
+
try {
|
|
92
|
+
// Authorization runs before ANY decoding or execution. Guarded on the field so a
|
|
93
|
+
// node without a predicate keeps the original path untouched.
|
|
94
|
+
if (self.authorization && await self.authorization.deny(actualStream, connection?.remotePeer?.toString())) return;
|
|
95
|
+
const processStream = async function* (source: AsyncIterable<Uint8ArrayList> | Iterable<Uint8ArrayList>) {
|
|
96
|
+
for await (const msg of source) {
|
|
97
|
+
const json = u8ToString(msg.subarray(), 'utf8');
|
|
98
|
+
const request = JSON.parse(json) as SyncRequest;
|
|
99
|
+
|
|
100
|
+
self.log(
|
|
101
|
+
'[Ring Zulu] Received sync request for block %s revision %s',
|
|
102
|
+
request.blockId,
|
|
103
|
+
request.rev ?? 'latest'
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const archive = await self.buildArchive(
|
|
107
|
+
request.blockId,
|
|
108
|
+
request.rev,
|
|
109
|
+
request.includePending,
|
|
110
|
+
request.maxRevisions
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const response: SyncResponse = archive
|
|
114
|
+
? { success: true, archive, responderId: stream.id ?? stream.stream?.id }
|
|
115
|
+
: { success: false, error: 'Block not found in local storage' };
|
|
116
|
+
|
|
117
|
+
self.log(
|
|
118
|
+
'[Ring Zulu] %s sync request for block %s',
|
|
119
|
+
response.success ? 'Fulfilled' : 'Failed',
|
|
120
|
+
request.blockId
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
yield new TextEncoder().encode(JSON.stringify(response));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Use the same streaming pipeline pattern as the repo service.
|
|
129
|
+
const responses = pipe(
|
|
130
|
+
actualStream,
|
|
131
|
+
(source: any) => lp.decode(source, { maxDataLength: MAX_CONTROL_MESSAGE_BYTES }),
|
|
132
|
+
processStream,
|
|
133
|
+
(source: any) => lp.encode(source)
|
|
134
|
+
);
|
|
135
|
+
for await (const chunk of responses) {
|
|
136
|
+
actualStream.send(chunk);
|
|
137
|
+
}
|
|
138
|
+
await actualStream.close();
|
|
139
|
+
} catch (error) {
|
|
140
|
+
self.log.error('Error handling sync request:', error);
|
|
141
|
+
try { actualStream.abort(error instanceof Error ? error : new Error(String(error))); } catch { /* ignore */ }
|
|
142
|
+
}
|
|
143
|
+
})();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Build a block archive from local storage — what a repair fetch on the other side receives.
|
|
148
|
+
* Shape and repo read both live in `storage/block-archive.ts`, shared with every other site that
|
|
149
|
+
* serves or fakes one, so a peer's answer cannot mean one thing here and another there.
|
|
150
|
+
*
|
|
151
|
+
* @param blockId - Block to retrieve
|
|
152
|
+
* @param rev - Optional specific revision
|
|
153
|
+
* @param includePending - Whether to include pending transactions
|
|
154
|
+
* @param maxRevisions - Maximum number of revisions to include
|
|
155
|
+
* @returns BlockArchive if found, undefined otherwise
|
|
156
|
+
*/
|
|
157
|
+
private async buildArchive(
|
|
158
|
+
blockId: string,
|
|
159
|
+
rev?: number,
|
|
160
|
+
_includePending?: boolean,
|
|
161
|
+
_maxRevisions?: number
|
|
162
|
+
): Promise<BlockArchive | undefined> {
|
|
163
|
+
try {
|
|
164
|
+
return await serveBlockArchive(this.repo, blockId, rev);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
this.log.error('Error building archive for block %s:', blockId, error);
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Factory function for creating a SyncService.
|
|
174
|
+
* Follows the libp2p service pattern.
|
|
175
|
+
*/
|
|
176
|
+
export const syncService = (init: SyncServiceInit = {}) =>
|
|
177
|
+
(components: SyncServiceComponents) => new SyncService(components, init);
|
|
178
|
+
|