@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
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { ClusterRecord, ITransactionValidator } from '@optimystic/db-core';
|
|
1
|
+
import type { ClusterRecord, ITransactionValidator, InvalidateRequest, CommitRequest, PendRequest, CollectionId } from '@optimystic/db-core';
|
|
2
|
+
import { blockIdsForTransforms } from '@optimystic/db-core';
|
|
3
|
+
import { buildDisputeResolutionProof, computeTargetHash, computeArbitratorSetHash, voteSigningPayload, arbitratorSetSigningPayload, VOTE_VERSION, type CertificateTarget } from './invalidation.js';
|
|
2
4
|
import type { PeerId, PrivateKey } from '@libp2p/interface';
|
|
3
5
|
import { sha256 } from 'multiformats/hashes/sha2';
|
|
4
6
|
import { base58btc } from 'multiformats/bases/base58';
|
|
@@ -39,6 +41,15 @@ export interface DisputeServiceInit {
|
|
|
39
41
|
config?: Partial<DisputeConfig>;
|
|
40
42
|
/** Select arbitrators for a dispute (next K peers beyond the original cluster) */
|
|
41
43
|
selectArbitrators: (blockId: string, excludePeers: string[], count: number) => Promise<PeerId[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Originates the durable reversal when a dispute resolves `challenger-wins`. The dissent
|
|
46
|
+
* coordinator (the node that initiated the dispute, holding the original record) builds the
|
|
47
|
+
* {@link InvalidateRequest} and hands it here to be driven through the critical cluster as a
|
|
48
|
+
* consensus-ordered invalidation; every member then applies it deterministically. Absent on
|
|
49
|
+
* nodes not wired to originate invalidations (today's default) — the in-memory status still flips,
|
|
50
|
+
* but nothing durable is written until this is supplied.
|
|
51
|
+
*/
|
|
52
|
+
onInvalidation?: (request: InvalidateRequest) => Promise<void> | void;
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
/**
|
|
@@ -57,6 +68,7 @@ export class DisputeService {
|
|
|
57
68
|
private readonly config: DisputeConfig;
|
|
58
69
|
private readonly engineHealth: EngineHealthMonitor;
|
|
59
70
|
private readonly selectArbitrators: DisputeServiceInit['selectArbitrators'];
|
|
71
|
+
private readonly onInvalidation?: DisputeServiceInit['onInvalidation'];
|
|
60
72
|
|
|
61
73
|
/** Active disputes initiated by this node */
|
|
62
74
|
private activeDisputes: Map<string, DisputeChallenge> = new Map();
|
|
@@ -66,6 +78,8 @@ export class DisputeService {
|
|
|
66
78
|
private resolvedChallenges: Map<string, DisputeChallenge> = new Map();
|
|
67
79
|
/** Track which transactions we've already disputed (prevent spam) */
|
|
68
80
|
private disputedTransactions: Set<string> = new Set();
|
|
81
|
+
/** Track which transactions we've already originated an invalidation for (fire once per messageHash) */
|
|
82
|
+
private invalidatedTransactions: Set<string> = new Set();
|
|
69
83
|
|
|
70
84
|
constructor(init: DisputeServiceInit) {
|
|
71
85
|
this.peerId = init.peerId;
|
|
@@ -76,6 +90,7 @@ export class DisputeService {
|
|
|
76
90
|
this.config = { ...DEFAULT_DISPUTE_CONFIG, ...init.config };
|
|
77
91
|
this.engineHealth = new EngineHealthMonitor(this.config);
|
|
78
92
|
this.selectArbitrators = init.selectArbitrators;
|
|
93
|
+
this.onInvalidation = init.onInvalidation;
|
|
79
94
|
}
|
|
80
95
|
|
|
81
96
|
/** Get the engine health monitor */
|
|
@@ -141,21 +156,8 @@ export class DisputeService {
|
|
|
141
156
|
: this.config.disputeArbitrationTimeoutMs * 2;
|
|
142
157
|
const expiration = timestamp + Math.max(defaultTtl, this.config.disputeArbitrationTimeoutMs);
|
|
143
158
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
originalMessageHash: record.messageHash,
|
|
147
|
-
originalRecord: record,
|
|
148
|
-
challengerPeerId: this.peerId.toString(),
|
|
149
|
-
challengerEvidence: evidence,
|
|
150
|
-
signature,
|
|
151
|
-
timestamp,
|
|
152
|
-
expiration,
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
this.activeDisputes.set(disputeId, challenge);
|
|
156
|
-
log('dispute-initiated', { disputeId, messageHash: record.messageHash });
|
|
157
|
-
|
|
158
|
-
// Select arbitrators and collect votes
|
|
159
|
+
// Select the arbitrator set FIRST so the challenge can carry it: each arbitrator folds the set's
|
|
160
|
+
// digest into the v3 vote it signs, binding every vote to the legitimately-selected set (#1).
|
|
159
161
|
const blockIds = record.coordinatingBlockIds ?? [];
|
|
160
162
|
const blockId = blockIds[0] ?? record.messageHash;
|
|
161
163
|
const originalPeers = Object.keys(record.peers);
|
|
@@ -166,16 +168,31 @@ export class DisputeService {
|
|
|
166
168
|
arbitrators = await this.selectArbitrators(blockId, originalPeers, arbitratorCount);
|
|
167
169
|
} catch (err) {
|
|
168
170
|
log('dispute-arbitrator-selection-failed', { disputeId, error: err instanceof Error ? err.message : String(err) });
|
|
169
|
-
this.activeDisputes.delete(disputeId);
|
|
170
171
|
return undefined;
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
if (arbitrators.length === 0) {
|
|
174
175
|
log('dispute-no-arbitrators', { disputeId });
|
|
175
|
-
this.activeDisputes.delete(disputeId);
|
|
176
176
|
return undefined;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
const arbitratorSet = arbitrators.map(a => a.toString());
|
|
180
|
+
|
|
181
|
+
const challenge: DisputeChallenge = {
|
|
182
|
+
disputeId,
|
|
183
|
+
originalMessageHash: record.messageHash,
|
|
184
|
+
originalRecord: record,
|
|
185
|
+
challengerPeerId: this.peerId.toString(),
|
|
186
|
+
challengerEvidence: evidence,
|
|
187
|
+
signature,
|
|
188
|
+
timestamp,
|
|
189
|
+
expiration,
|
|
190
|
+
arbitratorSet,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
this.activeDisputes.set(disputeId, challenge);
|
|
194
|
+
log('dispute-initiated', { disputeId, messageHash: record.messageHash });
|
|
195
|
+
|
|
179
196
|
// Send challenge to all arbitrators and collect votes
|
|
180
197
|
const votes = await this.collectVotes(challenge, arbitrators);
|
|
181
198
|
const resolution = this.resolveDispute(challenge, votes);
|
|
@@ -187,6 +204,10 @@ export class DisputeService {
|
|
|
187
204
|
// Apply reputation effects
|
|
188
205
|
this.applyReputationEffects(resolution, record);
|
|
189
206
|
|
|
207
|
+
// On a proven-invalid transaction, originate the durable reversal through the cluster. The
|
|
208
|
+
// challenger-selected `arbitratorSet` is bound into the proof (#1).
|
|
209
|
+
await this.maybeInvalidate(resolution, record, arbitratorSet);
|
|
210
|
+
|
|
190
211
|
// Broadcast resolution
|
|
191
212
|
await this.broadcastResolution(resolution, arbitrators, originalPeers);
|
|
192
213
|
|
|
@@ -207,6 +228,12 @@ export class DisputeService {
|
|
|
207
228
|
async handleChallenge(challenge: DisputeChallenge): Promise<ArbitrationVote> {
|
|
208
229
|
log('dispute-handle-challenge', { disputeId: challenge.disputeId });
|
|
209
230
|
|
|
231
|
+
// Bind every vote to the disputed transaction AND the legitimately-selected arbitrator set: derive
|
|
232
|
+
// the reversal target the same way the originator/apply path does (so the verifier recomputes an
|
|
233
|
+
// identical targetHash), digest the set the challenger carried, and sign over both (#1, #2).
|
|
234
|
+
const targetHash = await this.computeChallengeTargetHash(challenge);
|
|
235
|
+
const setHash = await computeArbitratorSetHash(challenge.arbitratorSet ?? []);
|
|
236
|
+
|
|
210
237
|
// Verify the challenge signature
|
|
211
238
|
const validSignature = await this.verifyDisputeSignature(
|
|
212
239
|
challenge.disputeId,
|
|
@@ -221,7 +248,7 @@ export class DisputeService {
|
|
|
221
248
|
engineId: 'unknown',
|
|
222
249
|
schemaHash: '',
|
|
223
250
|
blockStateHashes: {},
|
|
224
|
-
});
|
|
251
|
+
}, targetHash, setHash);
|
|
225
252
|
}
|
|
226
253
|
|
|
227
254
|
// Re-execute the transaction to produce our own evidence
|
|
@@ -244,7 +271,7 @@ export class DisputeService {
|
|
|
244
271
|
engineId: 'unknown',
|
|
245
272
|
schemaHash: '',
|
|
246
273
|
blockStateHashes: {},
|
|
247
|
-
});
|
|
274
|
+
}, targetHash, setHash);
|
|
248
275
|
}
|
|
249
276
|
|
|
250
277
|
// Compare our evidence with the challenger's
|
|
@@ -257,7 +284,22 @@ export class DisputeService {
|
|
|
257
284
|
vote = 'agree-with-majority';
|
|
258
285
|
}
|
|
259
286
|
|
|
260
|
-
return this.makeVote(challenge.disputeId, vote, evidence);
|
|
287
|
+
return this.makeVote(challenge.disputeId, vote, evidence, targetHash, setHash);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Derives the v2 target hash binding a vote to the disputed transaction: its `messageHash` plus the
|
|
292
|
+
* reversal target (the committed action being reversed and the blocks it wrote), extracted from the
|
|
293
|
+
* challenge's `originalRecord` exactly as {@link extractInvalidationTarget} does on the originate/apply
|
|
294
|
+
* side. A record with no extractable target yields an empty target — the resulting vote still verifies
|
|
295
|
+
* self-consistently but will not match a real reversal, which is correct (no real reversal exists).
|
|
296
|
+
*/
|
|
297
|
+
private async computeChallengeTargetHash(challenge: DisputeChallenge): Promise<string> {
|
|
298
|
+
const target = DisputeService.extractInvalidationTarget(challenge.originalRecord);
|
|
299
|
+
const certTarget: CertificateTarget = target
|
|
300
|
+
? { invalidatedActionId: target.actionId, blockIds: target.blockIds }
|
|
301
|
+
: { invalidatedActionId: '', blockIds: [] };
|
|
302
|
+
return computeTargetHash(challenge.originalRecord.messageHash, certTarget);
|
|
261
303
|
}
|
|
262
304
|
|
|
263
305
|
/**
|
|
@@ -373,6 +415,96 @@ export class DisputeService {
|
|
|
373
415
|
}
|
|
374
416
|
}
|
|
375
417
|
|
|
418
|
+
/**
|
|
419
|
+
* When a dispute resolves `challenger-wins`, originate the durable invalidation. Builds the
|
|
420
|
+
* independently-verifiable {@link buildDisputeResolutionProof proof} and the {@link InvalidateRequest}
|
|
421
|
+
* from the disputed transaction, then hands it to the injected `onInvalidation` originator (which
|
|
422
|
+
* drives it through the critical cluster). Fires at most once per disputed transaction. A no-op
|
|
423
|
+
* when no originator is wired (the in-memory status still flips via {@link getDisputeStatus}).
|
|
424
|
+
*/
|
|
425
|
+
private async maybeInvalidate(resolution: DisputeResolution, record: ClusterRecord, arbitratorSet: string[]): Promise<void> {
|
|
426
|
+
if (resolution.outcome !== 'challenger-wins' || !this.onInvalidation) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (this.invalidatedTransactions.has(record.messageHash)) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const target = DisputeService.extractInvalidationTarget(record);
|
|
434
|
+
if (!target) {
|
|
435
|
+
log('dispute-invalidation-no-target', { disputeId: resolution.disputeId, messageHash: record.messageHash });
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Bind the legitimately-selected arbitrator set (#1): the challenger signs (disputeId, target, set)
|
|
440
|
+
// so a third-party relay cannot swap in its own cohort. Same target derivation as the apply path.
|
|
441
|
+
const certTarget: CertificateTarget = { invalidatedActionId: target.actionId, blockIds: target.blockIds };
|
|
442
|
+
const targetHash = await computeTargetHash(record.messageHash, certTarget);
|
|
443
|
+
const setHash = await computeArbitratorSetHash(arbitratorSet);
|
|
444
|
+
const arbitratorSetSignature = await this.signArbitratorSet(resolution.disputeId, targetHash, setHash);
|
|
445
|
+
|
|
446
|
+
this.invalidatedTransactions.add(record.messageHash);
|
|
447
|
+
const request: InvalidateRequest = {
|
|
448
|
+
invalidatedActionId: target.actionId,
|
|
449
|
+
invalidatedRev: target.rev,
|
|
450
|
+
blockIds: target.blockIds,
|
|
451
|
+
collectionId: target.collectionId,
|
|
452
|
+
resolution: buildDisputeResolutionProof(resolution, record.messageHash, {
|
|
453
|
+
arbitratorSet,
|
|
454
|
+
challengerPeerId: this.peerId.toString(),
|
|
455
|
+
arbitratorSetSignature,
|
|
456
|
+
}),
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
try {
|
|
460
|
+
await this.onInvalidation(request);
|
|
461
|
+
log('dispute-invalidation-originated', {
|
|
462
|
+
disputeId: resolution.disputeId,
|
|
463
|
+
invalidatedActionId: target.actionId,
|
|
464
|
+
blockCount: target.blockIds.length,
|
|
465
|
+
});
|
|
466
|
+
} catch (err) {
|
|
467
|
+
// Roll back the once-guard so a retry can re-originate.
|
|
468
|
+
this.invalidatedTransactions.delete(record.messageHash);
|
|
469
|
+
log('dispute-invalidation-originate-failed', {
|
|
470
|
+
disputeId: resolution.disputeId,
|
|
471
|
+
error: err instanceof Error ? err.message : String(err),
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Derives the invalidation target — the committed action, its revision, the blocks it wrote, and
|
|
478
|
+
* its owning collection — from the disputed record. Prefers the commit operation (the disputed
|
|
479
|
+
* transaction is committed); falls back to the pend operation defensively.
|
|
480
|
+
*/
|
|
481
|
+
private static extractInvalidationTarget(record: ClusterRecord): { actionId: string; rev: number; blockIds: string[]; collectionId: CollectionId } | undefined {
|
|
482
|
+
for (const operation of record.message.operations) {
|
|
483
|
+
if ('commit' in operation) {
|
|
484
|
+
const commit = operation.commit as CommitRequest;
|
|
485
|
+
return {
|
|
486
|
+
actionId: commit.actionId,
|
|
487
|
+
rev: commit.rev,
|
|
488
|
+
blockIds: commit.blockIds,
|
|
489
|
+
collectionId: commit.headerId ?? record.coordinatingBlockIds?.[0] ?? commit.blockIds[0]!,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
for (const operation of record.message.operations) {
|
|
494
|
+
if ('pend' in operation) {
|
|
495
|
+
const pend = operation.pend as PendRequest;
|
|
496
|
+
const blockIds = blockIdsForTransforms(pend.transforms);
|
|
497
|
+
return {
|
|
498
|
+
actionId: pend.actionId,
|
|
499
|
+
rev: pend.rev ?? 0,
|
|
500
|
+
blockIds,
|
|
501
|
+
collectionId: record.coordinatingBlockIds?.[0] ?? blockIds[0]!,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
507
|
+
|
|
376
508
|
/** Broadcast resolution to all interested parties */
|
|
377
509
|
private async broadcastResolution(
|
|
378
510
|
resolution: DisputeResolution,
|
|
@@ -405,13 +537,18 @@ export class DisputeService {
|
|
|
405
537
|
private async makeVote(
|
|
406
538
|
disputeId: string,
|
|
407
539
|
vote: ArbitrationVote['vote'],
|
|
408
|
-
evidence: ValidationEvidence
|
|
540
|
+
evidence: ValidationEvidence,
|
|
541
|
+
targetHash: string,
|
|
542
|
+
setHash: string
|
|
409
543
|
): Promise<ArbitrationVote> {
|
|
410
|
-
|
|
411
|
-
|
|
544
|
+
// Target- and set-bound v3 payload: binds the vote to the specific transaction being reversed (#2)
|
|
545
|
+
// AND the legitimately-selected arbitrator set (#1) so a genuine vote can neither be replayed against
|
|
546
|
+
// an unrelated transaction nor presented under a swapped cohort.
|
|
547
|
+
const payloadBytes = voteSigningPayload(disputeId, vote, evidence.computedHash, targetHash, setHash);
|
|
412
548
|
const sigBytes = await this.privateKey.sign(payloadBytes);
|
|
413
549
|
|
|
414
550
|
return {
|
|
551
|
+
version: VOTE_VERSION,
|
|
415
552
|
disputeId,
|
|
416
553
|
arbitratorPeerId: this.peerId.toString(),
|
|
417
554
|
vote,
|
|
@@ -433,6 +570,16 @@ export class DisputeService {
|
|
|
433
570
|
return uint8ArrayToString(sigBytes, 'base64url');
|
|
434
571
|
}
|
|
435
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Sign the arbitrator-set binding `(disputeId, target, arbitratorSet)` with the challenger's key.
|
|
575
|
+
* Carried on the proof as {@link DisputeResolutionProof.arbitratorSetSignature}; a verifier validates
|
|
576
|
+
* it against this peer's embedded key (`challengerPeerId`), so a relay cannot substitute its own cohort.
|
|
577
|
+
*/
|
|
578
|
+
private async signArbitratorSet(disputeId: string, targetHash: string, setHash: string): Promise<string> {
|
|
579
|
+
const sigBytes = await this.privateKey.sign(arbitratorSetSigningPayload(disputeId, targetHash, setHash));
|
|
580
|
+
return uint8ArrayToString(sigBytes, 'base64url');
|
|
581
|
+
}
|
|
582
|
+
|
|
436
583
|
private async verifyDisputeSignature(
|
|
437
584
|
disputeId: string,
|
|
438
585
|
signature: string,
|
package/src/dispute/index.ts
CHANGED
|
@@ -15,3 +15,45 @@ export {
|
|
|
15
15
|
DEFAULT_DISPUTE_CONFIG,
|
|
16
16
|
} from './types.js';
|
|
17
17
|
export { selectArbitrators } from './arbitrator-selection.js';
|
|
18
|
+
export {
|
|
19
|
+
buildDisputeResolutionProof,
|
|
20
|
+
verifyInvalidationCertificate,
|
|
21
|
+
computeRevertedBlock,
|
|
22
|
+
computeTargetHash,
|
|
23
|
+
computeArbitratorSetHash,
|
|
24
|
+
voteSigningPayload,
|
|
25
|
+
arbitratorSetSigningPayload,
|
|
26
|
+
applyInvalidation,
|
|
27
|
+
hashBlockContent,
|
|
28
|
+
DELETED_BLOCK_RESTORE,
|
|
29
|
+
VOTE_VERSION,
|
|
30
|
+
type CertificateTarget,
|
|
31
|
+
type ArbitratorSetBinding,
|
|
32
|
+
type ArbitratorSetRecompute,
|
|
33
|
+
type ArbitratorSetRecomputeContext,
|
|
34
|
+
type ArbitratorSetVerdict,
|
|
35
|
+
type UnanchoredAcceptanceInfo,
|
|
36
|
+
type VerifyCertificateOptions,
|
|
37
|
+
type RevertedComputation,
|
|
38
|
+
type InvalidationContext,
|
|
39
|
+
type ApplyInvalidationParams,
|
|
40
|
+
type ApplyInvalidationResult,
|
|
41
|
+
} from './invalidation.js';
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
cascadeInvalidate,
|
|
45
|
+
contentEqualityReevaluator,
|
|
46
|
+
DEFAULT_CASCADE_CONFIG,
|
|
47
|
+
type CascadeConfig,
|
|
48
|
+
type CollectionEnv,
|
|
49
|
+
type InvalidatedPair,
|
|
50
|
+
type CascadeCandidate,
|
|
51
|
+
type CascadeVerdict,
|
|
52
|
+
type Reevaluate,
|
|
53
|
+
type CascadeSeed,
|
|
54
|
+
type CascadeInput,
|
|
55
|
+
type CascadeChild,
|
|
56
|
+
type CascadeStanding,
|
|
57
|
+
type CascadeEscalation,
|
|
58
|
+
type CascadeResult,
|
|
59
|
+
} from './cascade.js';
|