@optimystic/db-p2p 0.13.4 → 0.14.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 +6 -6
- package/dist/src/cluster/block-transfer-service.d.ts +67 -8
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +101 -62
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/client.d.ts +18 -1
- package/dist/src/cluster/client.d.ts.map +1 -1
- package/dist/src/cluster/client.js +55 -39
- package/dist/src/cluster/client.js.map +1 -1
- package/dist/src/cluster/cluster-error.d.ts +38 -0
- package/dist/src/cluster/cluster-error.d.ts.map +1 -0
- package/dist/src/cluster/cluster-error.js +51 -0
- package/dist/src/cluster/cluster-error.js.map +1 -0
- package/dist/src/cluster/cluster-repo.d.ts +135 -3
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +333 -58
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-cert.d.ts +63 -0
- package/dist/src/cluster/commit-cert.d.ts.map +1 -0
- package/dist/src/cluster/commit-cert.js +108 -0
- package/dist/src/cluster/commit-cert.js.map +1 -0
- package/dist/src/cluster/service.d.ts +46 -11
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +97 -33
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +13 -0
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +34 -4
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/bootstrap-evidence-builder.d.ts +59 -0
- package/dist/src/cohort-topic/bootstrap-evidence-builder.d.ts.map +1 -0
- package/dist/src/cohort-topic/bootstrap-evidence-builder.js +79 -0
- package/dist/src/cohort-topic/bootstrap-evidence-builder.js.map +1 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.d.ts +81 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.d.ts.map +1 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.js +93 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.js.map +1 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.d.ts +108 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.d.ts.map +1 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.js +108 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.js.map +1 -0
- package/dist/src/cohort-topic/change-bridge.d.ts +65 -0
- package/dist/src/cohort-topic/change-bridge.d.ts.map +1 -0
- package/dist/src/cohort-topic/change-bridge.js +76 -0
- package/dist/src/cohort-topic/change-bridge.js.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.d.ts +74 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.d.ts.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.js +87 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.js.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.d.ts +42 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.d.ts.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.js +57 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.js.map +1 -0
- package/dist/src/cohort-topic/fret-trust-anchor.d.ts +100 -0
- package/dist/src/cohort-topic/fret-trust-anchor.d.ts.map +1 -0
- package/dist/src/cohort-topic/fret-trust-anchor.js +115 -0
- package/dist/src/cohort-topic/fret-trust-anchor.js.map +1 -0
- package/dist/src/cohort-topic/host.d.ts +573 -0
- package/dist/src/cohort-topic/host.d.ts.map +1 -0
- package/dist/src/cohort-topic/host.js +1460 -0
- package/dist/src/cohort-topic/host.js.map +1 -0
- package/dist/src/cohort-topic/index.d.ts +14 -0
- package/dist/src/cohort-topic/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/index.js +14 -0
- package/dist/src/cohort-topic/index.js.map +1 -0
- package/dist/src/cohort-topic/membership-publish-sink.d.ts +14 -0
- package/dist/src/cohort-topic/membership-publish-sink.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership-publish-sink.js +17 -0
- package/dist/src/cohort-topic/membership-publish-sink.js.map +1 -0
- package/dist/src/cohort-topic/membership-source.d.ts +36 -0
- package/dist/src/cohort-topic/membership-source.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership-source.js +58 -0
- package/dist/src/cohort-topic/membership-source.js.map +1 -0
- package/dist/src/cohort-topic/peer-codec.d.ts +18 -0
- package/dist/src/cohort-topic/peer-codec.d.ts.map +1 -0
- package/dist/src/cohort-topic/peer-codec.js +26 -0
- package/dist/src/cohort-topic/peer-codec.js.map +1 -0
- package/dist/src/cohort-topic/peer-sig.d.ts +52 -0
- package/dist/src/cohort-topic/peer-sig.d.ts.map +1 -0
- package/dist/src/cohort-topic/peer-sig.js +83 -0
- package/dist/src/cohort-topic/peer-sig.js.map +1 -0
- package/dist/src/cohort-topic/protocols.d.ts +49 -0
- package/dist/src/cohort-topic/protocols.d.ts.map +1 -0
- package/dist/src/cohort-topic/protocols.js +58 -0
- package/dist/src/cohort-topic/protocols.js.map +1 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.d.ts +49 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.d.ts.map +1 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.js +42 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.js.map +1 -0
- package/dist/src/cohort-topic/size-estimator.d.ts +16 -0
- package/dist/src/cohort-topic/size-estimator.d.ts.map +1 -0
- package/dist/src/cohort-topic/size-estimator.js +16 -0
- package/dist/src/cohort-topic/size-estimator.js.map +1 -0
- package/dist/src/cohort-topic/stream-util.d.ts +19 -0
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -0
- package/dist/src/cohort-topic/stream-util.js +76 -0
- package/dist/src/cohort-topic/stream-util.js.map +1 -0
- package/dist/src/cohort-topic/threshold-crypto.d.ts +94 -0
- package/dist/src/cohort-topic/threshold-crypto.d.ts.map +1 -0
- package/dist/src/cohort-topic/threshold-crypto.js +178 -0
- package/dist/src/cohort-topic/threshold-crypto.js.map +1 -0
- package/dist/src/cohort-topic/topic-router.d.ts +41 -0
- package/dist/src/cohort-topic/topic-router.d.ts.map +1 -0
- package/dist/src/cohort-topic/topic-router.js +63 -0
- package/dist/src/cohort-topic/topic-router.js.map +1 -0
- package/dist/src/dispute/cascade.d.ts +179 -0
- package/dist/src/dispute/cascade.d.ts.map +1 -0
- package/dist/src/dispute/cascade.js +315 -0
- package/dist/src/dispute/cascade.js.map +1 -0
- package/dist/src/dispute/client.d.ts +2 -1
- package/dist/src/dispute/client.d.ts.map +1 -1
- package/dist/src/dispute/client.js +12 -3
- package/dist/src/dispute/client.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +41 -1
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +147 -21
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/index.d.ts +2 -0
- package/dist/src/dispute/index.d.ts.map +1 -1
- package/dist/src/dispute/index.js +2 -0
- package/dist/src/dispute/index.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +266 -0
- package/dist/src/dispute/invalidation.d.ts.map +1 -0
- package/dist/src/dispute/invalidation.js +405 -0
- package/dist/src/dispute/invalidation.js.map +1 -0
- package/dist/src/dispute/types.d.ts +14 -0
- package/dist/src/dispute/types.d.ts.map +1 -1
- package/dist/src/dispute/types.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +8 -1
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +67 -8
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +57 -3
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +523 -6
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/matchmaking/aggregate-counts.d.ts +67 -0
- package/dist/src/matchmaking/aggregate-counts.d.ts.map +1 -0
- package/dist/src/matchmaking/aggregate-counts.js +60 -0
- package/dist/src/matchmaking/aggregate-counts.js.map +1 -0
- package/dist/src/matchmaking/index.d.ts +20 -0
- package/dist/src/matchmaking/index.d.ts.map +1 -0
- package/dist/src/matchmaking/index.js +20 -0
- package/dist/src/matchmaking/index.js.map +1 -0
- package/dist/src/matchmaking/module.d.ts +181 -0
- package/dist/src/matchmaking/module.d.ts.map +1 -0
- package/dist/src/matchmaking/module.js +221 -0
- package/dist/src/matchmaking/module.js.map +1 -0
- package/dist/src/matchmaking/protocols.d.ts +37 -0
- package/dist/src/matchmaking/protocols.d.ts.map +1 -0
- package/dist/src/matchmaking/protocols.js +42 -0
- package/dist/src/matchmaking/protocols.js.map +1 -0
- package/dist/src/matchmaking/provider-manager.d.ts +52 -0
- package/dist/src/matchmaking/provider-manager.d.ts.map +1 -0
- package/dist/src/matchmaking/provider-manager.js +74 -0
- package/dist/src/matchmaking/provider-manager.js.map +1 -0
- package/dist/src/matchmaking/query-handler.d.ts +34 -0
- package/dist/src/matchmaking/query-handler.d.ts.map +1 -0
- package/dist/src/matchmaking/query-handler.js +62 -0
- package/dist/src/matchmaking/query-handler.js.map +1 -0
- package/dist/src/matchmaking/query-transport.d.ts +180 -0
- package/dist/src/matchmaking/query-transport.d.ts.map +1 -0
- package/dist/src/matchmaking/query-transport.js +315 -0
- package/dist/src/matchmaking/query-transport.js.map +1 -0
- package/dist/src/matchmaking/seeker-manager.d.ts +39 -0
- package/dist/src/matchmaking/seeker-manager.d.ts.map +1 -0
- package/dist/src/matchmaking/seeker-manager.js +49 -0
- package/dist/src/matchmaking/seeker-manager.js.map +1 -0
- package/dist/src/matchmaking/seeker-walk-client.d.ts +127 -0
- package/dist/src/matchmaking/seeker-walk-client.d.ts.map +1 -0
- package/dist/src/matchmaking/seeker-walk-client.js +189 -0
- package/dist/src/matchmaking/seeker-walk-client.js.map +1 -0
- package/dist/src/matchmaking/traffic-validation.d.ts +128 -0
- package/dist/src/matchmaking/traffic-validation.d.ts.map +1 -0
- package/dist/src/matchmaking/traffic-validation.js +105 -0
- package/dist/src/matchmaking/traffic-validation.js.map +1 -0
- package/dist/src/network/network-manager-service.d.ts +4 -2
- package/dist/src/network/network-manager-service.d.ts.map +1 -1
- package/dist/src/network/network-manager-service.js +9 -3
- package/dist/src/network/network-manager-service.js.map +1 -1
- package/dist/src/protocol-client.d.ts +25 -0
- package/dist/src/protocol-client.d.ts.map +1 -1
- package/dist/src/protocol-client.js +126 -4
- package/dist/src/protocol-client.js.map +1 -1
- package/dist/src/reactivity/forwarder-host.d.ts +198 -0
- package/dist/src/reactivity/forwarder-host.d.ts.map +1 -0
- package/dist/src/reactivity/forwarder-host.js +355 -0
- package/dist/src/reactivity/forwarder-host.js.map +1 -0
- package/dist/src/reactivity/index.d.ts +19 -0
- package/dist/src/reactivity/index.d.ts.map +1 -0
- package/dist/src/reactivity/index.js +19 -0
- package/dist/src/reactivity/index.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts +70 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -0
- package/dist/src/reactivity/notify-transport.js +111 -0
- package/dist/src/reactivity/notify-transport.js.map +1 -0
- package/dist/src/reactivity/origination-manager.d.ts +110 -0
- package/dist/src/reactivity/origination-manager.d.ts.map +1 -0
- package/dist/src/reactivity/origination-manager.js +129 -0
- package/dist/src/reactivity/origination-manager.js.map +1 -0
- package/dist/src/reactivity/protocols.d.ts +43 -0
- package/dist/src/reactivity/protocols.d.ts.map +1 -0
- package/dist/src/reactivity/protocols.js +50 -0
- package/dist/src/reactivity/protocols.js.map +1 -0
- package/dist/src/reactivity/push-state-gossip.d.ts +132 -0
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -0
- package/dist/src/reactivity/push-state-gossip.js +231 -0
- package/dist/src/reactivity/push-state-gossip.js.map +1 -0
- package/dist/src/reactivity/recover-transport.d.ts +167 -0
- package/dist/src/reactivity/recover-transport.d.ts.map +1 -0
- package/dist/src/reactivity/recover-transport.js +308 -0
- package/dist/src/reactivity/recover-transport.js.map +1 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.d.ts +142 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.d.ts.map +1 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.js +223 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.js.map +1 -0
- package/dist/src/reactivity/subscriber-registry.d.ts +47 -0
- package/dist/src/reactivity/subscriber-registry.d.ts.map +1 -0
- package/dist/src/reactivity/subscriber-registry.js +87 -0
- package/dist/src/reactivity/subscriber-registry.js.map +1 -0
- package/dist/src/reactivity/subscription-manager.d.ts +221 -0
- package/dist/src/reactivity/subscription-manager.d.ts.map +1 -0
- package/dist/src/reactivity/subscription-manager.js +302 -0
- package/dist/src/reactivity/subscription-manager.js.map +1 -0
- package/dist/src/reactivity/topic-bytes.d.ts +32 -0
- package/dist/src/reactivity/topic-bytes.d.ts.map +1 -0
- package/dist/src/reactivity/topic-bytes.js +34 -0
- package/dist/src/reactivity/topic-bytes.js.map +1 -0
- package/dist/src/repo/client.d.ts.map +1 -1
- package/dist/src/repo/client.js +51 -19
- package/dist/src/repo/client.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +9 -0
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +65 -22
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +20 -0
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +101 -16
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/service.d.ts +46 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +79 -45
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/rpc-deadline.d.ts +37 -0
- package/dist/src/rpc-deadline.d.ts.map +1 -0
- package/dist/src/rpc-deadline.js +31 -0
- package/dist/src/rpc-deadline.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +2 -0
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +95 -2
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +25 -0
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +53 -2
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +193 -9
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/sync/client.d.ts +4 -1
- package/dist/src/sync/client.d.ts.map +1 -1
- package/dist/src/sync/client.js +5 -2
- package/dist/src/sync/client.js.map +1 -1
- package/dist/src/testing/cohort-topic-mesh-harness.d.ts +219 -0
- package/dist/src/testing/cohort-topic-mesh-harness.d.ts.map +1 -0
- package/dist/src/testing/cohort-topic-mesh-harness.js +467 -0
- package/dist/src/testing/cohort-topic-mesh-harness.js.map +1 -0
- package/dist/src/testing/matchmaking-mesh-harness.d.ts +187 -0
- package/dist/src/testing/matchmaking-mesh-harness.d.ts.map +1 -0
- package/dist/src/testing/matchmaking-mesh-harness.js +358 -0
- package/dist/src/testing/matchmaking-mesh-harness.js.map +1 -0
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +23 -1
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/reactivity-mesh-harness.d.ts +298 -0
- package/dist/src/testing/reactivity-mesh-harness.d.ts.map +1 -0
- package/dist/src/testing/reactivity-mesh-harness.js +663 -0
- package/dist/src/testing/reactivity-mesh-harness.js.map +1 -0
- package/package.json +7 -4
- package/src/cluster/block-transfer-service.ts +133 -68
- package/src/cluster/client.ts +64 -45
- package/src/cluster/cluster-error.ts +64 -0
- package/src/cluster/cluster-repo.ts +405 -55
- package/src/cluster/commit-cert.ts +139 -0
- package/src/cluster/service.ts +116 -44
- package/src/cluster/spread-on-churn.ts +328 -285
- package/src/cohort-topic/bootstrap-evidence-builder.ts +122 -0
- package/src/cohort-topic/bootstrap-evidence-verifiers.ts +132 -0
- package/src/cohort-topic/bootstrap-parent-reference.ts +159 -0
- package/src/cohort-topic/change-bridge.ts +109 -0
- package/src/cohort-topic/cohort-gossip-driver.ts +144 -0
- package/src/cohort-topic/cohort-gossip-transport.ts +74 -0
- package/src/cohort-topic/fret-trust-anchor.ts +153 -0
- package/src/cohort-topic/host.ts +2175 -0
- package/src/cohort-topic/index.ts +13 -0
- package/src/cohort-topic/membership-publish-sink.ts +20 -0
- package/src/cohort-topic/membership-source.ts +68 -0
- package/src/cohort-topic/peer-codec.ts +31 -0
- package/src/cohort-topic/peer-sig.ts +86 -0
- package/src/cohort-topic/protocols.ts +71 -0
- package/src/cohort-topic/reactivity-membership-gate.ts +77 -0
- package/src/cohort-topic/size-estimator.ts +16 -0
- package/src/cohort-topic/stream-util.ts +87 -0
- package/src/cohort-topic/threshold-crypto.ts +239 -0
- package/src/cohort-topic/topic-router.ts +77 -0
- package/src/dispute/cascade.ts +517 -0
- package/src/dispute/client.ts +12 -2
- package/src/dispute/dispute-service.ts +171 -24
- package/src/dispute/index.ts +42 -0
- package/src/dispute/invalidation.ts +587 -0
- package/src/dispute/types.ts +14 -0
- package/src/index.ts +4 -0
- package/src/libp2p-key-network.ts +67 -9
- package/src/libp2p-node-base.ts +633 -14
- package/src/matchmaking/aggregate-counts.ts +104 -0
- package/src/matchmaking/index.ts +20 -0
- package/src/matchmaking/module.ts +363 -0
- package/src/matchmaking/protocols.ts +51 -0
- package/src/matchmaking/provider-manager.ts +95 -0
- package/src/matchmaking/query-handler.ts +88 -0
- package/src/matchmaking/query-transport.ts +483 -0
- package/src/matchmaking/seeker-manager.ts +64 -0
- package/src/matchmaking/seeker-walk-client.ts +293 -0
- package/src/matchmaking/traffic-validation.ts +195 -0
- package/src/network/network-manager-service.ts +9 -2
- package/src/protocol-client.ts +119 -5
- package/src/reactivity/forwarder-host.ts +438 -0
- package/src/reactivity/index.ts +19 -0
- package/src/reactivity/notify-transport.ts +144 -0
- package/src/reactivity/origination-manager.ts +192 -0
- package/src/reactivity/protocols.ts +61 -0
- package/src/reactivity/push-state-gossip.ts +291 -0
- package/src/reactivity/recover-transport.ts +408 -0
- package/src/reactivity/rotation-rereg-scheduler.ts +256 -0
- package/src/reactivity/subscriber-registry.ts +96 -0
- package/src/reactivity/subscription-manager.ts +450 -0
- package/src/reactivity/topic-bytes.ts +37 -0
- package/src/repo/client.ts +54 -19
- package/src/repo/cluster-coordinator.ts +66 -26
- package/src/repo/coordinator-repo.ts +99 -15
- package/src/repo/service.ts +90 -42
- package/src/rpc-deadline.ts +45 -0
- package/src/storage/block-storage.ts +106 -3
- package/src/storage/i-block-storage.ts +27 -0
- package/src/storage/storage-repo.ts +209 -13
- package/src/sync/client.ts +5 -2
- package/src/testing/cohort-topic-mesh-harness.ts +613 -0
- package/src/testing/matchmaking-mesh-harness.ts +475 -0
- package/src/testing/mesh-harness.ts +22 -2
- package/src/testing/reactivity-mesh-harness.ts +922 -0
package/README.md
CHANGED
|
@@ -93,9 +93,9 @@ graph TD
|
|
|
93
93
|
|
|
94
94
|
%% Network communication
|
|
95
95
|
B -.->|"/db-p2p/repo/1.0.0"| C
|
|
96
|
-
E -.->|"/
|
|
97
|
-
E -.->|"/
|
|
98
|
-
E -.->|"/
|
|
96
|
+
E -.->|"/optimystic/<network>/cluster/1.0.0"| G1
|
|
97
|
+
E -.->|"/optimystic/<network>/cluster/1.0.0"| G2
|
|
98
|
+
E -.->|"/optimystic/<network>/cluster/1.0.0"| G3
|
|
99
99
|
```
|
|
100
100
|
|
|
101
101
|
### Repo Layer: External Client Interface
|
|
@@ -203,7 +203,7 @@ Handles incoming consensus requests from coordinators:
|
|
|
203
203
|
|
|
204
204
|
```typescript
|
|
205
205
|
class ClusterService implements Startable {
|
|
206
|
-
// Protocol: /
|
|
206
|
+
// Protocol: /optimystic/<network>/cluster/1.0.0 (built from protocolPrefix)
|
|
207
207
|
// Handles ClusterRecord updates for consensus
|
|
208
208
|
}
|
|
209
209
|
```
|
|
@@ -319,8 +319,8 @@ The package integrates deeply with libp2p for networking:
|
|
|
319
319
|
// Node creation with integrated services
|
|
320
320
|
const node = await createLibp2pNode({
|
|
321
321
|
services: {
|
|
322
|
-
repo: repoService({
|
|
323
|
-
cluster: clusterService({
|
|
322
|
+
repo: repoService({ protocolPrefix: '/optimystic/<network>' }),
|
|
323
|
+
cluster: clusterService({ protocolPrefix: '/optimystic/<network>' })
|
|
324
324
|
}
|
|
325
325
|
});
|
|
326
326
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Startable } from '@libp2p/interface';
|
|
2
|
-
import type { IRepo, PeerId, IPeerNetwork } from '@optimystic/db-core';
|
|
2
|
+
import type { IRepo, PeerId, IPeerNetwork, ActionId, ActionRev, IBlock, BlockId } from '@optimystic/db-core';
|
|
3
3
|
import { ProtocolClient } from '../protocol-client.js';
|
|
4
4
|
export declare const buildBlockTransferProtocol: (protocolPrefix?: string) => string;
|
|
5
5
|
/** Request to transfer blocks */
|
|
@@ -11,6 +11,16 @@ export interface BlockTransferRequest {
|
|
|
11
11
|
reason: 'rebalance' | 'replication' | 'recovery';
|
|
12
12
|
/** For push: base64-encoded block data per block ID */
|
|
13
13
|
blockData?: Record<string, string>;
|
|
14
|
+
/**
|
|
15
|
+
* For push: the source's revision metadata per block ID. Carries the sender's
|
|
16
|
+
* `state.latest` so the replica's `latest` matches the source instead of being
|
|
17
|
+
* fabricated. Optional: an older sender omits it and the receiver falls back to a
|
|
18
|
+
* deterministic rev-1 replica (see {@link IBlockStorage.saveReplica}).
|
|
19
|
+
*/
|
|
20
|
+
blockMeta?: Record<string, {
|
|
21
|
+
rev: number;
|
|
22
|
+
actionId: ActionId;
|
|
23
|
+
}>;
|
|
14
24
|
}
|
|
15
25
|
/** Response with block data */
|
|
16
26
|
export interface BlockTransferResponse {
|
|
@@ -19,6 +29,21 @@ export interface BlockTransferResponse {
|
|
|
19
29
|
/** Block IDs that couldn't be found/transferred */
|
|
20
30
|
missing: string[];
|
|
21
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Repo capability the service needs: read access for `handlePull` plus a local
|
|
34
|
+
* "save replica" path for `handlePush`. The replica path must land in the node's
|
|
35
|
+
* *local* storage (not the cluster-coordinated repo), so it is a distinct method
|
|
36
|
+
* from the `IRepo` commit funnel. `StorageRepo` implements this.
|
|
37
|
+
*/
|
|
38
|
+
export interface IBlockReplicaStore extends IRepo {
|
|
39
|
+
/**
|
|
40
|
+
* Persist a replica of a block received out-of-band (churn re-replication).
|
|
41
|
+
* Seeds metadata if absent, advances `latest` monotonically, and makes the block
|
|
42
|
+
* durably servable via `get`. Idempotent for a fixed `(rev, actionId)`; a no-op
|
|
43
|
+
* (still durable) when an equal-or-newer revision is already present.
|
|
44
|
+
*/
|
|
45
|
+
saveReplicatedBlock(blockId: BlockId, block: IBlock, source?: ActionRev): Promise<void>;
|
|
46
|
+
}
|
|
22
47
|
export interface BlockTransferServiceInit {
|
|
23
48
|
protocolPrefix?: string;
|
|
24
49
|
}
|
|
@@ -27,7 +52,7 @@ export interface BlockTransferServiceComponents {
|
|
|
27
52
|
handle: (...args: any[]) => Promise<void>;
|
|
28
53
|
unhandle: (...args: any[]) => Promise<void>;
|
|
29
54
|
};
|
|
30
|
-
repo:
|
|
55
|
+
repo: IBlockReplicaStore;
|
|
31
56
|
}
|
|
32
57
|
/**
|
|
33
58
|
* Libp2p service that handles incoming block transfer requests.
|
|
@@ -45,9 +70,13 @@ export declare class BlockTransferService implements Startable {
|
|
|
45
70
|
stop(): Promise<void>;
|
|
46
71
|
private handleRequest;
|
|
47
72
|
private handlePull;
|
|
73
|
+
/**
|
|
74
|
+
* Persist pushed blocks into local storage so the new owner holds a durable
|
|
75
|
+
* replica after churn. A block is reported `accepted` only if it was both
|
|
76
|
+
* received (parseable) AND successfully persisted; a parse or persist failure
|
|
77
|
+
* surfaces it as `missing` so the sender does not falsely treat it as replicated.
|
|
78
|
+
*/
|
|
48
79
|
private handlePush;
|
|
49
|
-
private readRequest;
|
|
50
|
-
private sendResponse;
|
|
51
80
|
}
|
|
52
81
|
/** Factory for creating BlockTransferService following the libp2p service pattern. */
|
|
53
82
|
export declare const blockTransferService: (init?: BlockTransferServiceInit) => (components: BlockTransferServiceComponents) => BlockTransferService;
|
|
@@ -57,9 +86,39 @@ export declare const blockTransferService: (init?: BlockTransferServiceInit) =>
|
|
|
57
86
|
export declare class BlockTransferClient extends ProtocolClient {
|
|
58
87
|
private readonly protocol;
|
|
59
88
|
constructor(peerId: PeerId, peerNetwork: IPeerNetwork, protocolPrefix?: string);
|
|
60
|
-
/**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Pull blocks from the remote peer.
|
|
91
|
+
*
|
|
92
|
+
* @param options Optional per-call deadlines/cancellation forwarded to the
|
|
93
|
+
* underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
|
|
94
|
+
* bounds waiting for the reply once connected; `signal` cancels the whole
|
|
95
|
+
* request. Omitting all of them preserves the previous uncapped behavior.
|
|
96
|
+
*/
|
|
97
|
+
pullBlocks(blockIds: string[], reason?: BlockTransferRequest['reason'], options?: {
|
|
98
|
+
signal?: AbortSignal;
|
|
99
|
+
dialTimeoutMs?: number;
|
|
100
|
+
responseTimeoutMs?: number;
|
|
101
|
+
}): Promise<BlockTransferResponse>;
|
|
102
|
+
/**
|
|
103
|
+
* Push blocks to the remote peer.
|
|
104
|
+
*
|
|
105
|
+
* @param blockMeta Optional per-block source revision metadata (the sender's
|
|
106
|
+
* `state.latest`). When provided, the receiver replicates at the source's
|
|
107
|
+
* `(rev, actionId)`; when omitted, it falls back to a deterministic rev-1 replica.
|
|
108
|
+
* @param options Optional per-call deadlines/cancellation forwarded to the
|
|
109
|
+
* underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
|
|
110
|
+
* bounds waiting for the reply once connected (so a peer that connects but goes
|
|
111
|
+
* silent throws {@link ResponseTimeoutError} instead of hanging); `signal`
|
|
112
|
+
* cancels the whole request. Omitting all of them preserves the previous
|
|
113
|
+
* uncapped behavior.
|
|
114
|
+
*/
|
|
115
|
+
pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason'], blockMeta?: Record<string, {
|
|
116
|
+
rev: number;
|
|
117
|
+
actionId: ActionId;
|
|
118
|
+
}>, options?: {
|
|
119
|
+
signal?: AbortSignal;
|
|
120
|
+
dialTimeoutMs?: number;
|
|
121
|
+
responseTimeoutMs?: number;
|
|
122
|
+
}): Promise<BlockTransferResponse>;
|
|
64
123
|
}
|
|
65
124
|
//# sourceMappingURL=block-transfer-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAU,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,7 +29,14 @@ export class BlockTransferService {
|
|
|
29
29
|
if (this.running)
|
|
30
30
|
return;
|
|
31
31
|
await this.registrar.handle(this.protocol, async (data) => {
|
|
32
|
-
|
|
32
|
+
// libp2p invokes the stream handler with the Stream as the FIRST positional argument
|
|
33
|
+
// (see cluster/repo/dispute services, which all use `(stream, connection)`). The block-
|
|
34
|
+
// transfer handler previously read `data.stream`, which is `undefined` for the positional
|
|
35
|
+
// shape — so `readRequest` ran `pipe(undefined, ...)` → "Empty pipeline", the receiver
|
|
36
|
+
// never replied, and every push/pull dialled this service hung with no response. Unwrap
|
|
37
|
+
// defensively (older shape passed `{ stream }`), mirroring sync/service.ts.
|
|
38
|
+
const stream = data?.stream ?? data;
|
|
39
|
+
await this.handleRequest(stream);
|
|
33
40
|
});
|
|
34
41
|
this.running = true;
|
|
35
42
|
log('started on %s', this.protocol);
|
|
@@ -42,31 +49,43 @@ export class BlockTransferService {
|
|
|
42
49
|
log('stopped');
|
|
43
50
|
}
|
|
44
51
|
async handleRequest(stream) {
|
|
52
|
+
const self = this;
|
|
45
53
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
// Read the request, process it, and write the response on ONE continuous duplex
|
|
55
|
+
// pipe (mirrors cluster/repo/dispute services). The earlier read-to-end-then-write
|
|
56
|
+
// design deadlocked over a real stream: the client sends one length-prefixed request
|
|
57
|
+
// and holds its write side open awaiting the reply, so a receiver that drained the
|
|
58
|
+
// source until end-of-stream blocked forever — and the reply, written only after
|
|
59
|
+
// teardown, hit a closed stream. Yielding the response as soon as the request is read
|
|
60
|
+
// keeps both sides live.
|
|
61
|
+
const responses = pipe(stream, (source) => lp.decode(source), async function* (source) {
|
|
62
|
+
for await (const msg of source) {
|
|
63
|
+
const request = JSON.parse(u8ToString(msg.subarray(), 'utf8'));
|
|
64
|
+
log('request type=%s blocks=%d reason=%s', request.type, request.blockIds.length, request.reason);
|
|
65
|
+
let response;
|
|
66
|
+
try {
|
|
67
|
+
response = request.type === 'pull'
|
|
68
|
+
? await self.handlePull(request)
|
|
69
|
+
: await self.handlePush(request);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
log('error: %s', error.message);
|
|
73
|
+
response = { blocks: {}, missing: [] };
|
|
74
|
+
}
|
|
75
|
+
log('response blocks=%d missing=%d', Object.keys(response.blocks).length, response.missing.length);
|
|
76
|
+
yield u8FromString(JSON.stringify(response), 'utf8');
|
|
77
|
+
return; // one request → one response per stream
|
|
78
|
+
}
|
|
79
|
+
}, (source) => lp.encode(source));
|
|
80
|
+
for await (const chunk of responses) {
|
|
81
|
+
stream.send(chunk);
|
|
65
82
|
}
|
|
83
|
+
await stream.close();
|
|
66
84
|
}
|
|
67
|
-
|
|
85
|
+
catch (err) {
|
|
86
|
+
log('error: %s', err.message);
|
|
68
87
|
try {
|
|
69
|
-
|
|
88
|
+
stream.abort(err instanceof Error ? err : new Error(String(err)));
|
|
70
89
|
}
|
|
71
90
|
catch { /* ignore */ }
|
|
72
91
|
}
|
|
@@ -86,52 +105,53 @@ export class BlockTransferService {
|
|
|
86
105
|
}
|
|
87
106
|
return { blocks, missing };
|
|
88
107
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Persist pushed blocks into local storage so the new owner holds a durable
|
|
110
|
+
* replica after churn. A block is reported `accepted` only if it was both
|
|
111
|
+
* received (parseable) AND successfully persisted; a parse or persist failure
|
|
112
|
+
* surfaces it as `missing` so the sender does not falsely treat it as replicated.
|
|
113
|
+
*/
|
|
92
114
|
async handlePush(request) {
|
|
93
115
|
const blocks = {};
|
|
94
116
|
const missing = [];
|
|
95
117
|
if (!request.blockData) {
|
|
96
118
|
return { blocks: {}, missing: request.blockIds };
|
|
97
119
|
}
|
|
98
|
-
// Accept pushed blocks — for each block, validate we received parseable data
|
|
99
120
|
for (const blockId of request.blockIds) {
|
|
100
121
|
const data = request.blockData[blockId];
|
|
101
|
-
if (data) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
JSON.parse(Buffer.from(data, 'base64').toString('utf8'));
|
|
105
|
-
blocks[blockId] = data;
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
missing.push(blockId);
|
|
109
|
-
}
|
|
122
|
+
if (!data) {
|
|
123
|
+
missing.push(blockId);
|
|
124
|
+
continue;
|
|
110
125
|
}
|
|
111
|
-
|
|
126
|
+
// Decode + parse the wire payload into an IBlock.
|
|
127
|
+
let block;
|
|
128
|
+
try {
|
|
129
|
+
block = JSON.parse(Buffer.from(data, 'base64').toString('utf8'));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
112
132
|
missing.push(blockId);
|
|
133
|
+
continue;
|
|
113
134
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
135
|
+
// `JSON.parse` accepts `null`/primitives as valid JSON. Persisting a falsy or
|
|
136
|
+
// header-less "block" would seed metadata with no materialization, making every
|
|
137
|
+
// later `get` throw. Reject such payloads as missing rather than poison storage.
|
|
138
|
+
if (block === null || typeof block !== 'object' || block.header === undefined) {
|
|
139
|
+
log('push:invalid block=%s (not a structurally valid block)', blockId);
|
|
140
|
+
missing.push(blockId);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// Persist locally. Only a received-AND-persisted block is reported accepted.
|
|
144
|
+
try {
|
|
145
|
+
const source = request.blockMeta?.[blockId];
|
|
146
|
+
await this.repo.saveReplicatedBlock(blockId, block, source);
|
|
147
|
+
blocks[blockId] = data;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
log('persist:fail block=%s err=%s', blockId, error.message);
|
|
151
|
+
missing.push(blockId);
|
|
122
152
|
}
|
|
123
|
-
});
|
|
124
|
-
if (messages.length === 0) {
|
|
125
|
-
throw new Error('No request received');
|
|
126
|
-
}
|
|
127
|
-
return JSON.parse(u8ToString(messages[0], 'utf8'));
|
|
128
|
-
}
|
|
129
|
-
async sendResponse(stream, response) {
|
|
130
|
-
const bytes = u8FromString(JSON.stringify(response), 'utf8');
|
|
131
|
-
const encoded = pipe([bytes], lp.encode);
|
|
132
|
-
for await (const chunk of encoded) {
|
|
133
|
-
stream.send(chunk);
|
|
134
153
|
}
|
|
154
|
+
return { blocks, missing };
|
|
135
155
|
}
|
|
136
156
|
}
|
|
137
157
|
/** Factory for creating BlockTransferService following the libp2p service pattern. */
|
|
@@ -146,19 +166,38 @@ export class BlockTransferClient extends ProtocolClient {
|
|
|
146
166
|
super(peerId, peerNetwork);
|
|
147
167
|
this.protocol = buildBlockTransferProtocol(protocolPrefix);
|
|
148
168
|
}
|
|
149
|
-
/**
|
|
150
|
-
|
|
169
|
+
/**
|
|
170
|
+
* Pull blocks from the remote peer.
|
|
171
|
+
*
|
|
172
|
+
* @param options Optional per-call deadlines/cancellation forwarded to the
|
|
173
|
+
* underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
|
|
174
|
+
* bounds waiting for the reply once connected; `signal` cancels the whole
|
|
175
|
+
* request. Omitting all of them preserves the previous uncapped behavior.
|
|
176
|
+
*/
|
|
177
|
+
async pullBlocks(blockIds, reason = 'rebalance', options) {
|
|
151
178
|
const request = { type: 'pull', blockIds, reason };
|
|
152
|
-
return await this.processMessage(request, this.protocol);
|
|
179
|
+
return await this.processMessage(request, this.protocol, options);
|
|
153
180
|
}
|
|
154
|
-
/**
|
|
155
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Push blocks to the remote peer.
|
|
183
|
+
*
|
|
184
|
+
* @param blockMeta Optional per-block source revision metadata (the sender's
|
|
185
|
+
* `state.latest`). When provided, the receiver replicates at the source's
|
|
186
|
+
* `(rev, actionId)`; when omitted, it falls back to a deterministic rev-1 replica.
|
|
187
|
+
* @param options Optional per-call deadlines/cancellation forwarded to the
|
|
188
|
+
* underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
|
|
189
|
+
* bounds waiting for the reply once connected (so a peer that connects but goes
|
|
190
|
+
* silent throws {@link ResponseTimeoutError} instead of hanging); `signal`
|
|
191
|
+
* cancels the whole request. Omitting all of them preserves the previous
|
|
192
|
+
* uncapped behavior.
|
|
193
|
+
*/
|
|
194
|
+
async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance', blockMeta, options) {
|
|
156
195
|
const blockData = {};
|
|
157
196
|
for (let i = 0; i < blockIds.length; i++) {
|
|
158
197
|
blockData[blockIds[i]] = Buffer.from(blockDataBuffers[i]).toString('base64');
|
|
159
198
|
}
|
|
160
|
-
const request = { type: 'push', blockIds, reason, blockData };
|
|
161
|
-
return await this.processMessage(request, this.protocol);
|
|
199
|
+
const request = { type: 'push', blockIds, reason, blockData, ...(blockMeta ? { blockMeta } : {}) };
|
|
200
|
+
return await this.processMessage(request, this.protocol, options);
|
|
162
201
|
}
|
|
163
202
|
}
|
|
164
203
|
//# sourceMappingURL=block-transfer-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-transfer-service.js","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACzC,OAAO,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;AAEnD,oBAAoB;AACpB,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AACxD,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAEvC,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,iBAAyB,EAAE,EAAU,EAAE,CACjF,GAAG,cAAc,GAAG,qBAAqB,GAAG,sBAAsB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"block-transfer-service.js","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import type { PeerId, IPeerNetwork, ICluster, ClusterRecord } from '@optimystic/db-core';
|
|
2
2
|
import { ProtocolClient } from '../protocol-client.js';
|
|
3
|
+
import { type RpcDeadlineOptions } from '../rpc-deadline.js';
|
|
3
4
|
export declare class ClusterClient extends ProtocolClient implements ICluster {
|
|
4
5
|
readonly protocolPrefix?: string | undefined;
|
|
5
6
|
private constructor();
|
|
6
7
|
/** Create a new client instance */
|
|
7
8
|
static create(peerId: PeerId, peerNetwork: IPeerNetwork, protocolPrefix?: string): ClusterClient;
|
|
8
|
-
update(record: ClusterRecord, hop?: number): Promise<ClusterRecord>;
|
|
9
|
+
update(record: ClusterRecord, hop?: number, options?: RpcDeadlineOptions): Promise<ClusterRecord>;
|
|
10
|
+
/**
|
|
11
|
+
* Record a coordinator-affinity hint for the block this record's op is
|
|
12
|
+
* coordinated on, so a follow-up op can dial `peerId` directly.
|
|
13
|
+
*
|
|
14
|
+
* The op lives at `record.message.operations[0]` — `record.message` is a
|
|
15
|
+
* RepoMessage `{ operations: [...] }`, NOT a bare `{ commit }`/`{ pend }`.
|
|
16
|
+
* Reading `record.message.commit`/`.pend` (the old code) always saw
|
|
17
|
+
* `undefined`, so this hint was dead code and never recorded anything.
|
|
18
|
+
*
|
|
19
|
+
* The key is `blockIdToBytes(<the coordinated block id>)` — the sha256 digest
|
|
20
|
+
* findCoordinator/recordCoordinator key the cache on — NOT raw utf8 of the id
|
|
21
|
+
* (which would never be retrieved). Commit anchors on blockIds[0] (where
|
|
22
|
+
* CoordinatorRepo runs consensus + verifyResponsibility), not tailId. Pend
|
|
23
|
+
* anchors on a real block id (blockIdsForTransforms), not a structural
|
|
24
|
+
* transforms field name. ClusterClient only ever carries commit/pend.
|
|
25
|
+
*/
|
|
9
26
|
private recordCoordinatorForRecordIfSupported;
|
|
10
27
|
}
|
|
11
28
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEtF,qBAAa,aAAc,SAAQ,cAAe,YAAW,QAAQ;IACL,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM;IAA/F,OAAO;IAIP,mCAAmC;WACrB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,aAAa;IAIjG,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,GAAE,MAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAyCzG;;;;;;;;;;;;;;;OAeG;YACW,qCAAqC;CAWpD"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { blockIdToBytes, blockIdsForTransforms } from '@optimystic/db-core';
|
|
1
2
|
import { ProtocolClient } from '../protocol-client.js';
|
|
2
3
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
4
|
+
import { isClusterErrorEnvelope, clusterErrorFromEnvelope } from './cluster-error.js';
|
|
5
|
+
import { withRpcDeadlineDefaults } from '../rpc-deadline.js';
|
|
3
6
|
export class ClusterClient extends ProtocolClient {
|
|
4
7
|
protocolPrefix;
|
|
5
8
|
constructor(peerId, peerNetwork, protocolPrefix) {
|
|
@@ -10,62 +13,75 @@ export class ClusterClient extends ProtocolClient {
|
|
|
10
13
|
static create(peerId, peerNetwork, protocolPrefix) {
|
|
11
14
|
return new ClusterClient(peerId, peerNetwork, protocolPrefix);
|
|
12
15
|
}
|
|
13
|
-
async update(record, hop = 0) {
|
|
16
|
+
async update(record, hop = 0, options) {
|
|
14
17
|
const message = {
|
|
15
18
|
operation: 'update',
|
|
16
19
|
record
|
|
17
20
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
// Every node registers the cluster service under its network-prefixed
|
|
22
|
+
// protocol id (`/optimystic/<network>/cluster/1.0.0`); the bare
|
|
23
|
+
// `/db-p2p/cluster/1.0.0` is never registered, so there is no legacy
|
|
24
|
+
// fallback to attempt — a single dial whose error propagates directly.
|
|
25
|
+
const protocol = (this.protocolPrefix ?? '/db-p2p') + '/cluster/1.0.0';
|
|
26
|
+
// Apply the client-level dial/response deadline so a silent cluster peer
|
|
27
|
+
// can't hang the coordinator forever; an explicit caller override wins.
|
|
28
|
+
const response = await this.processMessage(message, protocol, withRpcDeadlineDefaults(options));
|
|
29
|
+
// A member that threw inside `update` replies with a structured error
|
|
30
|
+
// envelope rather than aborting the stream; rethrow the server's real
|
|
31
|
+
// error (preserving name/code) so the coordinator sees the true cause.
|
|
32
|
+
if (isClusterErrorEnvelope(response)) {
|
|
33
|
+
throw clusterErrorFromEnvelope(response);
|
|
22
34
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
response = await this.processMessage(message, '/db-p2p/cluster/1.0.0');
|
|
27
|
-
}
|
|
28
|
-
catch (fallbackErr) {
|
|
29
|
-
// Throw original error - fallback protocol is likely not registered
|
|
30
|
-
throw err;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
throw err;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (response?.redirect?.peers?.length) {
|
|
35
|
+
const redirectResponse = response;
|
|
36
|
+
if (redirectResponse?.redirect?.peers?.length) {
|
|
38
37
|
if (hop >= 2) {
|
|
39
38
|
throw new Error('Redirect loop detected in ClusterClient (max hops reached)');
|
|
40
39
|
}
|
|
41
40
|
const currentIdStr = this.peerId.toString();
|
|
42
|
-
const next =
|
|
41
|
+
const next = redirectResponse.redirect.peers.find((p) => p.id !== currentIdStr) ?? redirectResponse.redirect.peers[0];
|
|
43
42
|
const nextId = peerIdFromString(next.id);
|
|
44
43
|
if (next.id === currentIdStr) {
|
|
45
44
|
throw new Error('Redirect loop detected in ClusterClient (same peer)');
|
|
46
45
|
}
|
|
47
|
-
this.recordCoordinatorForRecordIfSupported(record, nextId);
|
|
46
|
+
await this.recordCoordinatorForRecordIfSupported(record, nextId);
|
|
48
47
|
const nextClient = ClusterClient.create(nextId, this.peerNetwork, this.protocolPrefix);
|
|
49
|
-
|
|
48
|
+
// Thread the caller's *original* options through the redirect hop (the
|
|
49
|
+
// recursive call re-applies its own defaults) so the deadline survives a redirect.
|
|
50
|
+
return await nextClient.update(record, hop + 1, options);
|
|
50
51
|
}
|
|
51
52
|
return response;
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Record a coordinator-affinity hint for the block this record's op is
|
|
56
|
+
* coordinated on, so a follow-up op can dial `peerId` directly.
|
|
57
|
+
*
|
|
58
|
+
* The op lives at `record.message.operations[0]` — `record.message` is a
|
|
59
|
+
* RepoMessage `{ operations: [...] }`, NOT a bare `{ commit }`/`{ pend }`.
|
|
60
|
+
* Reading `record.message.commit`/`.pend` (the old code) always saw
|
|
61
|
+
* `undefined`, so this hint was dead code and never recorded anything.
|
|
62
|
+
*
|
|
63
|
+
* The key is `blockIdToBytes(<the coordinated block id>)` — the sha256 digest
|
|
64
|
+
* findCoordinator/recordCoordinator key the cache on — NOT raw utf8 of the id
|
|
65
|
+
* (which would never be retrieved). Commit anchors on blockIds[0] (where
|
|
66
|
+
* CoordinatorRepo runs consensus + verifyResponsibility), not tailId. Pend
|
|
67
|
+
* anchors on a real block id (blockIdsForTransforms), not a structural
|
|
68
|
+
* transforms field name. ClusterClient only ever carries commit/pend.
|
|
69
|
+
*/
|
|
70
|
+
async recordCoordinatorForRecordIfSupported(record, peerId) {
|
|
71
|
+
const op = record.message.operations[0];
|
|
72
|
+
if (!op)
|
|
73
|
+
return;
|
|
74
|
+
let id;
|
|
75
|
+
if ('commit' in op)
|
|
76
|
+
id = op.commit.blockIds[0];
|
|
77
|
+
else if ('pend' in op)
|
|
78
|
+
id = blockIdsForTransforms(op.pend.transforms)[0];
|
|
79
|
+
if (id == null)
|
|
80
|
+
return;
|
|
81
|
+
const kbytes = await blockIdToBytes(id);
|
|
82
|
+
const pn = this.peerNetwork;
|
|
83
|
+
if (typeof pn?.recordCoordinator === 'function')
|
|
84
|
+
pn.recordCoordinator(kbytes, peerId);
|
|
69
85
|
}
|
|
70
86
|
}
|
|
71
87
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"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"}
|