@optimystic/db-p2p 0.13.5 → 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 +7 -0
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +49 -5
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +45 -3
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +522 -5
- 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 +13 -0
- package/dist/src/protocol-client.d.ts.map +1 -1
- package/dist/src/protocol-client.js +74 -2
- 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 -23
- package/dist/src/repo/client.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 +49 -6
- package/src/libp2p-node-base.ts +620 -12
- 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 +64 -3
- 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 -23
- 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
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cohort-topic FRET host (`docs/cohort-topic.md` §FRET integration L768-803).
|
|
3
|
+
*
|
|
4
|
+
* Composes the db-core substrate (participant-facing {@link CohortTopicService} + cohort-side
|
|
5
|
+
* {@link CohortMemberEngine}) over the FRET + libp2p ports and runs it as a service on one node:
|
|
6
|
+
*
|
|
7
|
+
* - registers the four `/optimystic/cohort-topic/1.0.0/*` protocols on the libp2p node;
|
|
8
|
+
* - sets FRET's activity handler so a `RouteAndMaybeAct`-routed `RegisterV1` runs the cohort decision;
|
|
9
|
+
* - binds the db-core ports to the FRET-backed adapters (router, gossip, membership, size estimator).
|
|
10
|
+
*
|
|
11
|
+
* **Per-served-coord scoping.** A topic's responsible cohort sits at `coord_0(_, topicId)` (and at
|
|
12
|
+
* `coord_d(P, topicId)` for `d ≥ 1`), which is unrelated to any node's own ring position. A node
|
|
13
|
+
* genuinely belongs to *many* cohorts — one per coord FRET routes to it — so this host keeps a lazy
|
|
14
|
+
* {@link CoordRegistry}: a `Map<servedCoord, CoordEngine>` where each {@link CoordEngine} owns the
|
|
15
|
+
* per-coord slice of state (its own store, gossip bus, willingness/traffic/renewal/cold-start, a
|
|
16
|
+
* {@link PromotionLifecycle} with coord-derived tier inputs, a {@link CohortMemberEngine}, its own
|
|
17
|
+
* {@link MembershipCertPublisher}, and its own real `k − x` threshold signer) and threshold-signs with
|
|
18
|
+
* the FRET cohort *around the served coord*. The node-wide collaborators (`hash`, `slots`, `barometer`,
|
|
19
|
+
* the FRET ports, the participant-facing service, and the verify-only verifier signer) stay singletons
|
|
20
|
+
* and are injected into each engine. The host recomputes the served coord from each decoded `RegisterV1`
|
|
21
|
+
* (`addressing.coord(treeTier, participantCoord, topicId)`), so both the activity callback and the direct
|
|
22
|
+
* `register` protocol handler dispatch to the right cohort.
|
|
23
|
+
*
|
|
24
|
+
* **Real threshold signatures.** Each coord engine assembles a genuine `k − x` cohort signature
|
|
25
|
+
* (a collected per-member Ed25519 multisig) over the new `/sign` protocol — see
|
|
26
|
+
* {@link FretCohortThresholdCrypto} — and drives a {@link MembershipCertPublisher}, so a remote
|
|
27
|
+
* `MembershipVerifier` can verify the served `MembershipCertV1` for real. Assembly needs the node's
|
|
28
|
+
* `options.privateKey`; key-less hosts compose but cannot threshold-sign (the publisher/promotion paths
|
|
29
|
+
* are simply not driven). The periodic membership refresh is exposed as the per-engine
|
|
30
|
+
* {@link CoordEngine.pumpMembership} / {@link CoordEngine.onStabilized} hooks for the gossip-cadence
|
|
31
|
+
* driver to call.
|
|
32
|
+
*
|
|
33
|
+
* **Anti-DoS + cold-start (gaps 6–7).** Each {@link CoordEngine} is injected its own per-coord anti-DoS
|
|
34
|
+
* guards — a `RegisterRateLimiter` (4/min per peer-topic), a `CorrelationReplayGuard` (60 s freshness),
|
|
35
|
+
* and a `TopicBudget` (2048 topics, LRU) — so a budget/limit at one coord is independent of another. The
|
|
36
|
+
* node-level {@link BootstrapEvidence} policy (one tier→verifier policy, no per-coord state) is built once
|
|
37
|
+
* and shared. db-core embeds no PoW / reputation scheme, so the host supplies the real verifiers
|
|
38
|
+
* ({@link createPoWVerifier} / {@link createReputationVerifier}) and the participant-side PoW minter
|
|
39
|
+
* ({@link createBootstrapEvidenceBuilder}): once configured, a node gates cold-root `bootstrap: true` at
|
|
40
|
+
* T2/T3 (PoW, or a referee reputation endorsement when offered, or a signed parent reference) and at T0/T1
|
|
41
|
+
* once a committed-existence backing is wired (a signed parent reference); a configured node with no such
|
|
42
|
+
* backing keeps T0/T1 permissive-but-logged so cold-root origination is not blocked
|
|
43
|
+
* (`cohort-topic-bootstrap-coldstart-origination-regression`), and an entirely unconfigured host stays
|
|
44
|
+
* permissive-but-logged at every tier (never an undefined gate). A cold-started tier-`d > 0` forwarder registers with
|
|
45
|
+
* its tier-`(d − 1)` parent by routing a forwarder-link frame over the router (gap 7), staying
|
|
46
|
+
* `awaiting_parent` until the ack.
|
|
47
|
+
*
|
|
48
|
+
* **Scope.** `followOn` derivation for a promoted-redirect arrival is parked in backlog
|
|
49
|
+
* (`cohort-topic-followon-derivation`); this milestone serves a **single tier-0 cohort**, so `followOn`
|
|
50
|
+
* stays `false` and tier-0 bootstrap instantiation goes through the `bootstrap: true` path. The
|
|
51
|
+
* behavioral substrate is validated at mock-tier by `test/cohort-topic/service.spec.ts` and end-to-end
|
|
52
|
+
* across a real multi-node cohort (real Ed25519 keys, mock transport routing the five protocols + FRET
|
|
53
|
+
* `routeAct`/`assembleCohort`) by `test/cohort-topic/live-tier.spec.ts`.
|
|
54
|
+
*/
|
|
55
|
+
import type { Libp2p } from "libp2p";
|
|
56
|
+
import type { PrivateKey } from "@libp2p/interface";
|
|
57
|
+
import type { FretService } from "p2p-fret";
|
|
58
|
+
import { LruMap, type BootstrapEvidenceDeps, type CohortGossipV1, type CohortTopicService, type CohortMemberEngine, type CohortSnapshotView, type CohortView, type CorrelationReplayGuardConfig, type DemotionNoticeV1, type Forwarder, type MembershipCertV1, type MembershipVerifier, type NodeProfile, type PromotionConfig, type PromotionNoticeV1, type RegisterRateLimiter, type RegisterRateLimiterConfig, type RegistrationRecord, type RenewReplyV1, type RenewV1, type RingCoord, type SignReplyV1, type SignRequestV1, type TopicBudgetConfig, type TopicTrafficV1, type TrustRoot } from "@optimystic/db-core";
|
|
59
|
+
import { FretCohortGossipTransport } from "./cohort-gossip-transport.js";
|
|
60
|
+
import { type BootstrapReputationView } from "./bootstrap-evidence-verifiers.js";
|
|
61
|
+
import { type BootstrapParentTopicView } from "./bootstrap-parent-reference.js";
|
|
62
|
+
import { type CohortTopicProtocols } from "./protocols.js";
|
|
63
|
+
export interface CohortTopicHostOptions {
|
|
64
|
+
/** Per-node tier profile. Default {@link coreProfile}. */
|
|
65
|
+
readonly profile?: NodeProfile;
|
|
66
|
+
/** Network name (namespaces the four protocol IDs); default uses the canonical IDs. */
|
|
67
|
+
readonly protocols?: CohortTopicProtocols;
|
|
68
|
+
/** Requested cohort size `wantK`. Default 16. */
|
|
69
|
+
readonly wantK?: number;
|
|
70
|
+
/** Threshold signers `minSigs = k − x`. Default {@link DEFAULT_MIN_SIGS}. */
|
|
71
|
+
readonly minSigs?: number;
|
|
72
|
+
/** Fan-out per tier `F`. Default 16. */
|
|
73
|
+
readonly fanout?: number;
|
|
74
|
+
/** Per-frame ceiling. Default {@link DEFAULT_STREAM_MAX_BYTES}. */
|
|
75
|
+
readonly maxBytes?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Gossip-round cadence in ms (the periodic driver tick). Default {@link DEFAULT_GOSSIP_INTERVAL_MS}
|
|
78
|
+
* (~one round). Each tick drives every live {@link CoordEngine}'s gossip broadcast, TTL sweep,
|
|
79
|
+
* membership-cert refresh, and demotion check; the refresh (5 min) and demotion hysteresis (5 min)
|
|
80
|
+
* self-gate on elapsed time, so a fast tick is safe.
|
|
81
|
+
*/
|
|
82
|
+
readonly gossipIntervalMs?: number;
|
|
83
|
+
/**
|
|
84
|
+
* The node's libp2p Ed25519 private key. Required for the live participant signer: register/renew
|
|
85
|
+
* bodies are peer-key-signed over their canonical image, and inbound register/`reattach` signatures
|
|
86
|
+
* are verified against the participant's claimed peer id. libp2p does not expose the key off
|
|
87
|
+
* `node.peerId`, so it is threaded explicitly (mirrors `clusterMember` / `DisputeService`, sourced
|
|
88
|
+
* from `options.privateKey ?? generateKeyPair('Ed25519')` in `libp2p-node-base.ts`). When omitted,
|
|
89
|
+
* the host falls back to the interim empty-string signer (one-time warn) and does **not** enforce
|
|
90
|
+
* inbound participant-signature verification, so unit tests compose without a key.
|
|
91
|
+
*/
|
|
92
|
+
readonly privateKey?: PrivateKey;
|
|
93
|
+
/**
|
|
94
|
+
* Anti-DoS guard wiring (gap 6). The per-{@link CoordEngine} guards (rate limiter, replay guard,
|
|
95
|
+
* topic budget) and the node-level bootstrap-evidence policy are always constructed with documented
|
|
96
|
+
* defaults; this lets a caller (or a test) tune them. Omit for production defaults.
|
|
97
|
+
*/
|
|
98
|
+
readonly antiDos?: CohortTopicAntiDosOptions;
|
|
99
|
+
/**
|
|
100
|
+
* Promotion / demotion lifecycle tuning (`cap_promote`, hysteresis windows, slope lookahead) applied
|
|
101
|
+
* to every {@link CoordEngine}'s {@link PromotionLifecycle}. Omit for the production defaults
|
|
102
|
+
* (`cap_promote = 64`, …); supply a lowered `capPromote` to drive promotion with a small participant
|
|
103
|
+
* count (the live-tier e2e). The single-cohort milestone never overrides `childCohortCount` / `treeTier`
|
|
104
|
+
* — those stay coord-derived — so only the count/load thresholds are tunable here.
|
|
105
|
+
*/
|
|
106
|
+
readonly promotion?: PromotionConfig;
|
|
107
|
+
/**
|
|
108
|
+
* Optional committed-state existence reader backing the **committed-tier (T0/T1)** parent-reference
|
|
109
|
+
* bootstrap-evidence check (`cohort-topic-bootstrap-parent-reference`). Given `coord_0(parentTopicId)`,
|
|
110
|
+
* returns whether the node locally knows the parent topic's committed cohort exists. Threaded from
|
|
111
|
+
* node-base when a coord-keyed committed-membership index is available; when omitted, T0/T1 parent-ref
|
|
112
|
+
* existence fails closed (a FRET-cached cert must not vouch for committed-tier existence — committed-tier
|
|
113
|
+
* integrity) while T2/T3 parent-ref still consults the FRET membership cache. See
|
|
114
|
+
* {@link createDefaultParentTopicView}.
|
|
115
|
+
*/
|
|
116
|
+
readonly committedParentTopicReader?: (coord: RingCoord) => boolean;
|
|
117
|
+
/**
|
|
118
|
+
* The participant's initial trust roots: the genesis-block-related cohorts, validated against the
|
|
119
|
+
* genesis block hash **out-of-band by the caller before seeding** (`docs/cohort-topic.md`
|
|
120
|
+
* §Bootstrapping trust). They are the base case of every attestation chain — a cert matching a root by
|
|
121
|
+
* `(coord, epoch, member-set)` is trusted directly, ahead of the FRET-ring direct anchor — so a forged
|
|
122
|
+
* cert for a genesis cohort is rejected even before the ring is consulted. Threaded straight into
|
|
123
|
+
* `createMembershipVerifier({ trustRoots })`.
|
|
124
|
+
*
|
|
125
|
+
* **Network-config, empty by default.** The concrete genesis-cohort set is a property of a specific
|
|
126
|
+
* network's genesis block; this is the typed seam, not a fabricated value. Omitted (the default `[]`)
|
|
127
|
+
* the verifier behaves exactly as with no roots — the chain bottoms out at the direct anchor / TOFU, so
|
|
128
|
+
* a network with no genesis cohort configured is never broken. Do **not** seed fake roots here.
|
|
129
|
+
*/
|
|
130
|
+
readonly genesisTrustRoots?: readonly TrustRoot[];
|
|
131
|
+
/**
|
|
132
|
+
* Wall clock (ms) the `/sign` membership endorser uses for its `stabilizedAt` far-future sanity bound
|
|
133
|
+
* (a member refuses to co-sign a cert whose `stabilizedAt` is more than a few seconds ahead of its own
|
|
134
|
+
* clock — `cohort-topic-sign-endorsement-payload-binding`). Defaults to {@link Date.now}, the right
|
|
135
|
+
* choice for a production node. A **virtual-time** test harness (which drives publish `stabilizedAt`
|
|
136
|
+
* from arbitrary explicit timestamps rather than wall clock) injects a clock that does not trip the
|
|
137
|
+
* bound — e.g. `() => Number.POSITIVE_INFINITY` — so its synthetic future timestamps are not rejected.
|
|
138
|
+
*/
|
|
139
|
+
readonly now?: () => number;
|
|
140
|
+
}
|
|
141
|
+
export type { BootstrapReputationView } from "./bootstrap-evidence-verifiers.js";
|
|
142
|
+
/**
|
|
143
|
+
* Anti-DoS wiring overrides for a {@link CohortTopicHost} (`docs/cohort-topic.md` §Anti-DoS).
|
|
144
|
+
*
|
|
145
|
+
* The rate limiter, replay guard, and topic budget are **per-served-coord** (they key on
|
|
146
|
+
* `(peer, topic)` / per-cohort topic state, which is coord-scoped) — one set is built per
|
|
147
|
+
* {@link CoordEngine} from these configs. The bootstrap-evidence policy is **node-level** (a
|
|
148
|
+
* tier→verifier policy with no per-coord state) and is shared by every engine.
|
|
149
|
+
*/
|
|
150
|
+
export interface CohortTopicAntiDosOptions {
|
|
151
|
+
/** Per-`(peer, topic)` register rate limiter. Default `register_rate_per_peer = 4 / 60 s`, exponential back-off. */
|
|
152
|
+
readonly rateLimiter?: RegisterRateLimiterConfig;
|
|
153
|
+
/** Correlation-id freshness + replay guard. Default `maxAge = 60 s`, `futureSkew = 5 s`. */
|
|
154
|
+
readonly replayGuard?: CorrelationReplayGuardConfig;
|
|
155
|
+
/** Per-cohort forwarder-state budget. Default `topics_max = 2048`, LRU by participant count. */
|
|
156
|
+
readonly topicBudget?: TopicBudgetConfig;
|
|
157
|
+
/**
|
|
158
|
+
* Bootstrap-evidence verifiers for cold-root instantiation. db-core embeds no PoW / reputation /
|
|
159
|
+
* committed-work scheme; inject the real checks here. Any verifier supplied wins over the defaults
|
|
160
|
+
* below; the gate is **never** left undefined (an unset gate means cold-root bootstrap is
|
|
161
|
+
* unauthenticated — `docs/cohort-topic.md` §Anti-DoS).
|
|
162
|
+
*/
|
|
163
|
+
readonly bootstrapEvidence?: BootstrapEvidenceDeps;
|
|
164
|
+
/**
|
|
165
|
+
* Optional peer-reputation view backing the **reputation-endorsement** evidence path: a *referee*
|
|
166
|
+
* peer-key-signs the bootstrap bound image, and the cohort admits it iff the signature verifies and
|
|
167
|
+
* the referee is sufficiently reputable here (not banned **and** below the deprioritize threshold).
|
|
168
|
+
* `PeerReputationService` satisfies this `{ isBanned, getScore }` shape directly. Supplying it (or any
|
|
169
|
+
* `bootstrapEvidence` override) makes the gate **configured**: the real PoW verifier runs, the referee
|
|
170
|
+
* verifier backs the reputation path, the real signed-parent-reference verifier backs the parent-ref path
|
|
171
|
+
* (permissive-but-logged only at T0/T1 when this host has no committed-existence backing — see
|
|
172
|
+
* {@link createBootstrapEvidencePolicy}), and any otherwise-unfilled verifier fails closed — so a
|
|
173
|
+
* banned/low-rep referee cannot slip the T2/T3 `PoW || reputation || parent-ref` disjunction. When omitted
|
|
174
|
+
* (and no `bootstrapEvidence` verifier is supplied), the gate is permissive-but-logged (the
|
|
175
|
+
* entirely-unconfigured interim node).
|
|
176
|
+
*/
|
|
177
|
+
readonly reputation?: BootstrapReputationView;
|
|
178
|
+
/**
|
|
179
|
+
* Proof-of-work difficulty (leading zero bits) the real PoW verifier requires. Default the db-core
|
|
180
|
+
* `DEFAULT_POW_DIFFICULTY_BITS`. A low value (e.g. `0`) keeps minting fast/deterministic in tests.
|
|
181
|
+
* Applies to both the cohort-side PoW verifier and this node's participant-side PoW builder.
|
|
182
|
+
*/
|
|
183
|
+
readonly powDifficultyBits?: number;
|
|
184
|
+
/**
|
|
185
|
+
* Strict "sufficient reputation" cutoff for a bootstrap referee — a referee with `getScore < this` is
|
|
186
|
+
* accepted. Default the reputation service's `deprioritize` threshold.
|
|
187
|
+
*/
|
|
188
|
+
readonly deprioritizeThreshold?: number;
|
|
189
|
+
/**
|
|
190
|
+
* Existence view backing the **signed parent-reference** evidence path (`verifyParentReference`). A test
|
|
191
|
+
* seam: when supplied it overrides *which* existence view the real verifier consults (the host default is
|
|
192
|
+
* built from the FRET membership cache + addressing + the optional
|
|
193
|
+
* {@link CohortTopicHostOptions.committedParentTopicReader}). It does **not** by itself make the gate
|
|
194
|
+
* "configured" — only a `reputation` view or a `bootstrapEvidence` override flips that (see
|
|
195
|
+
* {@link createBootstrapEvidencePolicy}); an unconfigured host stays permissive and never consults this
|
|
196
|
+
* view. Pair it with `reputation`/`bootstrapEvidence` to exercise the real parent-reference verifier. See
|
|
197
|
+
* {@link createDefaultParentTopicView} / {@link createParentReferenceVerifier}.
|
|
198
|
+
*/
|
|
199
|
+
readonly parentTopicView?: BootstrapParentTopicView;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* One cohort the node serves, bound to a FRET-routed coordinate. Owns the per-coord slice of cohort
|
|
203
|
+
* state; the node-wide collaborators are injected (see {@link CoordEngineContext}).
|
|
204
|
+
*/
|
|
205
|
+
export interface CoordEngine {
|
|
206
|
+
/** The served ring coordinate this engine is the cohort for. */
|
|
207
|
+
readonly servedCoord: RingCoord;
|
|
208
|
+
/** Tree tier `d` the served coord was instantiated at (fixed by the first register). */
|
|
209
|
+
readonly treeTier: number;
|
|
210
|
+
/** Cohort-side register/renew/sweep engine driven by the protocol handlers + activity callback. */
|
|
211
|
+
readonly engine: CohortMemberEngine;
|
|
212
|
+
/** The FRET-assembled cohort around {@link servedCoord} (self prepended, deduped) + epoch. */
|
|
213
|
+
cohort(): CohortSnapshotView;
|
|
214
|
+
/**
|
|
215
|
+
* The cohort member peer-id strings this engine served under `epoch` (the **current** or the
|
|
216
|
+
* immediately-**prior** observed epoch), or `undefined` if it tracked no such epoch. Drives the `/sign`
|
|
217
|
+
* `"rotation"` endorsement gate: a member endorses a hand-off from `prevEpoch` only when it was a member
|
|
218
|
+
* of the cohort at that epoch. Returns `undefined` past the two-deep history (a rapid double rotation —
|
|
219
|
+
* the requester then re-anchors). See `cohort-topic-trust-anchor-rotation-production`.
|
|
220
|
+
*/
|
|
221
|
+
cohortIdentityAt(epoch: Uint8Array): readonly string[] | undefined;
|
|
222
|
+
/** True iff this engine currently holds any registration record (a cold probe leaves it empty). */
|
|
223
|
+
hasState(): boolean;
|
|
224
|
+
/** True iff this engine holds the record for `(topicId, participantId)` — the renewal lookup key. */
|
|
225
|
+
holds(topicId: Uint8Array, participantId: Uint8Array): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* This cohort's locally-known direct registration records for `topicId` (the cohort-side read the
|
|
228
|
+
* matchmaking `QueryV1` handler / aggregate-count producer serve from — `docs/matchmaking.md`
|
|
229
|
+
* §Seeker query). A renewed record is live; a TTL-swept one is gone after the next `gossipRound`.
|
|
230
|
+
*/
|
|
231
|
+
records(topicId: Uint8Array): readonly RegistrationRecord[];
|
|
232
|
+
/**
|
|
233
|
+
* This cohort's current gossip-derived traffic barometer for `topicId` (own last-published counts +
|
|
234
|
+
* siblings' last-gossiped summaries + `directParticipants` from the store). The matchmaking `QueryV1`
|
|
235
|
+
* reply attaches it and the seeker hang-out decision consumes it (`docs/matchmaking.md` §Hang-out vs.
|
|
236
|
+
* continue). Non-mutating — a synchronous read over the same in-memory state a `gossipRound` mutates,
|
|
237
|
+
* lagging at most one gossip round (it reflects the last frozen summaries, never raw mid-round counts).
|
|
238
|
+
*/
|
|
239
|
+
topicTraffic(topicId: Uint8Array): TopicTrafficV1;
|
|
240
|
+
/**
|
|
241
|
+
* Publish a fresh threshold-signed `MembershipCertV1` on a cohort-membership-change / stabilization
|
|
242
|
+
* event (republishes only when the first `k − x` members changed). Returns the cert if published.
|
|
243
|
+
* Resolves `undefined` if no republish was needed or the quorum was unreachable this round.
|
|
244
|
+
*/
|
|
245
|
+
onStabilized(now: number): Promise<MembershipCertV1 | undefined>;
|
|
246
|
+
/**
|
|
247
|
+
* Periodic membership-cert refresh hook for the gossip-cadence driver to call (republishes once
|
|
248
|
+
* `T_membership_refresh` has elapsed). Returns the cert if (re)published, else `undefined`.
|
|
249
|
+
*/
|
|
250
|
+
pumpMembership(now: number): Promise<MembershipCertV1 | undefined>;
|
|
251
|
+
/**
|
|
252
|
+
* One gossip round: TTL-sweep stale records (firing the `evicted` deltas), freeze the per-topic
|
|
253
|
+
* traffic summaries, drain the accumulated record/eviction deltas, and broadcast a signed
|
|
254
|
+
* {@link CohortGossipV1} (willingness/load/traffic + deltas) to the cohort. Returns the broadcast
|
|
255
|
+
* frame, or `undefined` when the engine is idle (no resident topics and no deltas → nothing to send).
|
|
256
|
+
*/
|
|
257
|
+
gossipRound(now: number): Promise<CohortGossipV1 | undefined>;
|
|
258
|
+
/**
|
|
259
|
+
* Time-driven demotion check across this engine's resident topics; broadcasts any threshold-signed
|
|
260
|
+
* {@link DemotionNoticeV1} the lifecycle returns (root tier-0 cohorts never demote). No-op without a
|
|
261
|
+
* signing key (the verify-only per-coord signer cannot assemble a notice).
|
|
262
|
+
*/
|
|
263
|
+
demotionTick(now: number): Promise<void>;
|
|
264
|
+
/** The merged per-member gossip view (willingness / load / per-topic summaries) for this cohort. */
|
|
265
|
+
cohortView(): CohortView;
|
|
266
|
+
/** True iff this engine currently serves `topicId` (holds a record or a cold-start forwarder for it). */
|
|
267
|
+
servesTopic(topicId: Uint8Array): boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Whether `topicId` currently occupies a slot in this coord's anti-DoS topic budget. A drained topic
|
|
270
|
+
* stays resident-but-cold (`{@link budgetParticipantCount} === 0`) until a new topic reuses its slot;
|
|
271
|
+
* after that reuse `budgetHasTopic` is `false`. Test/diagnostic introspection over the per-coord budget
|
|
272
|
+
* (distinct from {@link servesTopic}, which a never-demoted cold-start forwarder keeps `true`).
|
|
273
|
+
*/
|
|
274
|
+
budgetHasTopic(topicId: Uint8Array): boolean;
|
|
275
|
+
/**
|
|
276
|
+
* The direct-participant count the topic budget last recorded for a resident `topicId` (its LRU
|
|
277
|
+
* eviction key), or `undefined` when `topicId` holds no budget slot. A resident reporting `0` has
|
|
278
|
+
* drained and is the next coldest-evictable candidate. Test/diagnostic introspection.
|
|
279
|
+
*/
|
|
280
|
+
budgetParticipantCount(topicId: Uint8Array): number | undefined;
|
|
281
|
+
/**
|
|
282
|
+
* The cold-start {@link Forwarder} this engine instantiated for `topicId`, or `undefined` if none.
|
|
283
|
+
* Exposes the parent-link lifecycle (`awaiting_parent` → `serving`) for the cold-start wiring (gap 7).
|
|
284
|
+
*/
|
|
285
|
+
forwarder(topicId: Uint8Array): Forwarder | undefined;
|
|
286
|
+
/** Whether `topicId` is in promoted mode here — reflects both locally-originated and remotely-applied state. */
|
|
287
|
+
isPromoted(topicId: Uint8Array): boolean;
|
|
288
|
+
/** Adopt a verified promotion notice into this cohort's local state (see {@link NoticeApplyTarget}). */
|
|
289
|
+
applyPromotionNotice(notice: PromotionNoticeV1, now: number): void;
|
|
290
|
+
/** Adopt a verified demotion notice into this cohort's local state (see {@link NoticeApplyTarget}). */
|
|
291
|
+
applyDemotionNotice(notice: DemotionNoticeV1, now: number): void;
|
|
292
|
+
/** Tear down the per-coord gossip subscription. */
|
|
293
|
+
close(): void;
|
|
294
|
+
}
|
|
295
|
+
/** Lazy `servedCoord → CoordEngine` registry: one engine per coord FRET routes to this node. */
|
|
296
|
+
export interface CoordRegistry {
|
|
297
|
+
/**
|
|
298
|
+
* The {@link CoordEngine} for `coord`, creating + caching it on first touch. `treeTier` and
|
|
299
|
+
* `participantCoord` seed a freshly-created engine's coord-derived tier inputs (ignored if the
|
|
300
|
+
* engine already exists). Synchronous, so concurrent activity callbacks for the same coord share
|
|
301
|
+
* one engine without a second being constructed.
|
|
302
|
+
*/
|
|
303
|
+
forCoord(coord: RingCoord, treeTier: number, participantCoord: Uint8Array): CoordEngine;
|
|
304
|
+
/** The engine holding the record for `(topicId, participantId)`, or `undefined` (renewal dispatch). */
|
|
305
|
+
findHolder(topicId: Uint8Array, participantId: Uint8Array): CoordEngine | undefined;
|
|
306
|
+
/**
|
|
307
|
+
* The already-instantiated engine for `coord`, or `undefined` — a pure lookup that (unlike
|
|
308
|
+
* {@link forCoord}) never creates one. The `/sign` `"rotation"` endorsement gate uses it to consult this
|
|
309
|
+
* node's prior-epoch membership for the requested coord without spuriously instantiating a cohort it
|
|
310
|
+
* does not serve.
|
|
311
|
+
*/
|
|
312
|
+
findByCoord(coord: RingCoord): CoordEngine | undefined;
|
|
313
|
+
/**
|
|
314
|
+
* The engine serving `topicId` at `treeTier`, or `undefined` (inbound promote/demote notice dispatch).
|
|
315
|
+
* A served coord embeds `(tier, topic)`, so at most one engine matches — the cohort the notice's
|
|
316
|
+
* signers belong to. `undefined` means this node serves no such cohort (e.g. a demotion arriving at a
|
|
317
|
+
* parent that does not track the child), so the notice is dropped rather than applied.
|
|
318
|
+
*/
|
|
319
|
+
findServing(topicId: Uint8Array, treeTier: number): CoordEngine | undefined;
|
|
320
|
+
/** Every live engine (stop + sweep). */
|
|
321
|
+
all(): readonly CoordEngine[];
|
|
322
|
+
/** Close every engine's gossip subscription. */
|
|
323
|
+
close(): void;
|
|
324
|
+
}
|
|
325
|
+
/** A running cohort-topic node: the participant service plus the per-coord cohort registry, on one FRET node. */
|
|
326
|
+
export interface CohortTopicHost {
|
|
327
|
+
/** Participant-facing substrate API (node scope, not a coord). */
|
|
328
|
+
readonly service: CohortTopicService;
|
|
329
|
+
/** Per-served-coord cohort engines (driven by the protocol handlers + activity callback). */
|
|
330
|
+
readonly registry: CoordRegistry;
|
|
331
|
+
/** The four registered protocol IDs. */
|
|
332
|
+
readonly protocols: CohortTopicProtocols;
|
|
333
|
+
/**
|
|
334
|
+
* The node's effective {@link NodeProfile} (Edge / Core). Exposed so a layered application (reactivity)
|
|
335
|
+
* can apply the same profile gate the host configured its engines with (e.g. Edge ⇒ subscriber-only).
|
|
336
|
+
*/
|
|
337
|
+
readonly profile: NodeProfile;
|
|
338
|
+
/**
|
|
339
|
+
* The intra-cohort gossip transport. Exposed so a layered application (reactivity push-state gossip) can
|
|
340
|
+
* ride its `broadcastOver` seam — the same one the promote-notice broadcast reuses — rather than standing
|
|
341
|
+
* up a second transport with duplicate cohort peer resolution.
|
|
342
|
+
*/
|
|
343
|
+
readonly gossipTransport: FretCohortGossipTransport;
|
|
344
|
+
/**
|
|
345
|
+
* The node-level `promote`-handler anti-abuse gate (per-`(peer, topic)` rate limiter + per-`(topic, tier)`
|
|
346
|
+
* `effectiveAt` high-water). Exposed for test/diagnostic introspection over its bounded-memory state — the
|
|
347
|
+
* limiter's `size` and the `highWater` `LruMap` — and so the gossip-cadence sweep wiring is observable.
|
|
348
|
+
*/
|
|
349
|
+
readonly promoteGate: PromoteGate;
|
|
350
|
+
/** Unregister the four protocols and tear down every coord engine. */
|
|
351
|
+
stop(): Promise<void>;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Build and start a {@link CohortTopicHost} on `node` over `fret`. Registers the four protocols and
|
|
355
|
+
* sets FRET's activity handler. Async because the node's ring coordinate is derived via FRET's
|
|
356
|
+
* `hashPeerId`.
|
|
357
|
+
*/
|
|
358
|
+
export declare function createCohortTopicHost(node: Libp2p, fret: FretService, options?: CohortTopicHostOptions): Promise<CohortTopicHost>;
|
|
359
|
+
/**
|
|
360
|
+
* Resolve an inbound `RenewV1` to the coord engine holding its record and run the renewal. A `RenewV1`
|
|
361
|
+
* carries no `treeTier`, so the held record — not a recomputed coord — names the cohort. If no engine
|
|
362
|
+
* on this host holds it (cross-node renewal, post-restart eviction, or replication lag), reply
|
|
363
|
+
* `unknown_registration` so the participant's failover loop tries its backups and ultimately re-runs
|
|
364
|
+
* the `d_max` lookup (§TTL and renewal) — never throw.
|
|
365
|
+
*/
|
|
366
|
+
export declare function resolveRenew(registry: CoordRegistry, renew: RenewV1, now: number): RenewReplyV1;
|
|
367
|
+
/** Dependencies for the `/sign` endorsement policy ({@link handleSignRequest}). */
|
|
368
|
+
export interface SignEndorsementDeps {
|
|
369
|
+
/** The node's libp2p key (signs the endorsement). Absent → every request is refused (no key to sign with). */
|
|
370
|
+
readonly privateKey: PrivateKey | undefined;
|
|
371
|
+
/** Self's dialable member id (UTF-8 peer-id string bytes). */
|
|
372
|
+
readonly selfMember: Uint8Array;
|
|
373
|
+
/** Cohort member peer-id strings around `coord` (self included). */
|
|
374
|
+
readonly cohortMembersAround: (coord: RingCoord) => string[];
|
|
375
|
+
/** Current cohort epoch (raw bytes) for `coord`. */
|
|
376
|
+
readonly currentEpoch: (coord: RingCoord) => Uint8Array;
|
|
377
|
+
/**
|
|
378
|
+
* For a `"rotation"` request: the cohort member peer-id strings this node served under `epoch` (the
|
|
379
|
+
* predecessor epoch carried as `request.cohortEpoch`), or `undefined` if it tracked no such epoch. The
|
|
380
|
+
* host wires it to the served coord's {@link CoordEngine.cohortIdentityAt}; absent → rotation
|
|
381
|
+
* endorsement is unavailable (a node with no per-coord rotation history refuses the hand-off).
|
|
382
|
+
*/
|
|
383
|
+
readonly priorCohortMembersAt?: (coord: RingCoord, epoch: Uint8Array) => readonly string[] | undefined;
|
|
384
|
+
/**
|
|
385
|
+
* The endorser's own canonical `MembershipCertV1` signable fields for `coord` at its **current** epoch,
|
|
386
|
+
* re-derived from its own cohort snapshot ({@link membershipCertSignable} with `stabilizedAt`
|
|
387
|
+
* omitted/ignored). Binds a `membership` endorsement to the endorser's independent view so a cohort
|
|
388
|
+
* insider cannot collect honest signatures over a cert the cohort never agreed to (falsified `members`
|
|
389
|
+
* or `cohortCoord`). `cohortEpoch` here MUST equal `bytesToB64url(currentEpoch(coord))`; `members` is the
|
|
390
|
+
* ascending-sorted base64url cohort set (the cert / sharding order). Absent → a `membership` request is
|
|
391
|
+
* refused (no view to bind the cert against). See `cohort-topic-sign-endorsement-payload-binding`.
|
|
392
|
+
*/
|
|
393
|
+
readonly expectedMembershipFields?: (coord: RingCoord) => {
|
|
394
|
+
cohortCoord: string;
|
|
395
|
+
cohortEpoch: string;
|
|
396
|
+
members: string[];
|
|
397
|
+
};
|
|
398
|
+
/**
|
|
399
|
+
* Wall clock (ms) for the `stabilizedAt` far-future sanity bound on a `membership` payload. The host
|
|
400
|
+
* wires {@link Date.now}; tests inject a fixed clock. Absent → the far-future bound is skipped (only
|
|
401
|
+
* finiteness is enforced), keeping minimal / key-less composition working.
|
|
402
|
+
*/
|
|
403
|
+
readonly now?: () => number;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* The `/sign` endorsement policy: decide whether to endorse a {@link SignRequestV1} and, if so, return
|
|
407
|
+
* this node's Ed25519 peer-key signature over the **exact** request payload. A member endorses only when
|
|
408
|
+
* both it and the requester are members of the cohort around `coord` under the request's epoch, **and**
|
|
409
|
+
* the payload bytes re-derive to something this node independently agrees to attest — so it never signs
|
|
410
|
+
* for outsiders and never blindly signs requester-supplied bytes. It still signs the exact image (no
|
|
411
|
+
* re-canonicalization), so the assembled signature verifies against what the requester collected.
|
|
412
|
+
*
|
|
413
|
+
* **Payload binding (cohort-topic-sign-endorsement-payload-binding).** The cohort + wire-epoch gates never
|
|
414
|
+
* inspect `request.payload`; without binding it an insider could collect honest signatures over a cert the
|
|
415
|
+
* cohort never agreed to. After those gates the endorser decodes the canonical signable image
|
|
416
|
+
* (`sig/payloads.ts` — a `JSON.parse`d array, NOT a `CohortMessageV1`) and refuses unless:
|
|
417
|
+
*
|
|
418
|
+
* - **all kinds** — the image tag matches the kind (`membership`→`MembershipCertV1`, etc.) and the
|
|
419
|
+
* payload-internal `cohortEpoch` equals this node's current epoch for `coord`; and
|
|
420
|
+
* - **`membership`** — `cohortCoord`, the full `members` list (deep-equal to the endorser's own ascending
|
|
421
|
+
* re-derived set), and a finite, not-far-future `stabilizedAt` all match its independent view
|
|
422
|
+
* ({@link SignEndorsementDeps.expectedMembershipFields}). Because epoch = H(members) in this host, the
|
|
423
|
+
* members and internal-epoch checks are mutually reinforcing: a forged member list cannot also carry the
|
|
424
|
+
* honest epoch. The participant verifier still independently re-checks `signers ⊆ cert.members`.
|
|
425
|
+
*
|
|
426
|
+
* The kind-specific **hot/cold** refinement for `promotion` / `demotion` (the endorser additionally
|
|
427
|
+
* requiring its own replicated `directParticipants` to be hot / cold) remains deferred: it needs a
|
|
428
|
+
* per-topic binding the `(payload, minSigs)` port can't carry and gossip record replication that is still
|
|
429
|
+
* interim. Parked in `cohort-topic-sign-endorsement-hotcold-refinement` (backlog).
|
|
430
|
+
*
|
|
431
|
+
* **`"rotation"` (epoch hand-off).** A rotation request carries the **prior** epoch as `cohortEpoch` and
|
|
432
|
+
* asks the outgoing cohort to sign the *successor* cert. The gate therefore checks **prior**-epoch
|
|
433
|
+
* membership instead of current: the endorser must have served the cohort at `prevEpoch`, and the
|
|
434
|
+
* requester must have been a member of that prior cohort too (the genuinely outgoing set). The verifier
|
|
435
|
+
* still independently re-checks `rotationSigners ⊆ predecessor-cert.members`, so this gate is the
|
|
436
|
+
* load-shedding sanity check, not the trust root. See `cohort-topic-trust-anchor-rotation-production`.
|
|
437
|
+
*/
|
|
438
|
+
export declare function handleSignRequest(request: SignRequestV1, fromPeerStr: string, deps: SignEndorsementDeps): Promise<SignReplyV1>;
|
|
439
|
+
/** A decoded `promote`-protocol frame, tagged by which notice it is. */
|
|
440
|
+
export type InboundNotice = {
|
|
441
|
+
readonly kind: "promotion";
|
|
442
|
+
readonly notice: PromotionNoticeV1;
|
|
443
|
+
} | {
|
|
444
|
+
readonly kind: "demotion";
|
|
445
|
+
readonly notice: DemotionNoticeV1;
|
|
446
|
+
};
|
|
447
|
+
/** Outcome of {@link verifyAndApplyNotice}. */
|
|
448
|
+
export type NoticeOutcome = "applied" | "untrusted" | "dropped";
|
|
449
|
+
/**
|
|
450
|
+
* Outcome of {@link handleInboundNotice} — the {@link NoticeOutcome}s plus the cheap pre-verify drops the
|
|
451
|
+
* anti-abuse gate adds before any signature work runs:
|
|
452
|
+
*
|
|
453
|
+
* - `"undecodable"` — the frame is neither a promotion nor a demotion notice.
|
|
454
|
+
* - `"rate-limited"` — the dialing `(peer, topic)` is over its `register_rate_per_peer` ceiling.
|
|
455
|
+
* - `"stale"` — the notice's `effectiveAt` is at or below the last *applied* notice for its
|
|
456
|
+
* `(topic, tier)` (a replay / out-of-order frame); dropped before `verifyMessage`.
|
|
457
|
+
*/
|
|
458
|
+
export type InboundNoticeResult = NoticeOutcome | "undecodable" | "rate-limited" | "stale";
|
|
459
|
+
/**
|
|
460
|
+
* Node-level anti-abuse state for the `promote` handler (`cohort-topic-promote-handler-verify-amplification`).
|
|
461
|
+
* The handler is node-level (one per node, not per coord), so unlike the per-{@link CoordEngine} register-path
|
|
462
|
+
* guards it owns its own instances here.
|
|
463
|
+
*/
|
|
464
|
+
export interface PromoteGate {
|
|
465
|
+
/**
|
|
466
|
+
* Per-`(peer, topic)` inbound-notice rate limiter (reuses the register-path limiter). A peer streaming
|
|
467
|
+
* forged notices at one topic is dropped once it exceeds the ceiling, before any verify / membership work.
|
|
468
|
+
*/
|
|
469
|
+
readonly rateLimiter: RegisterRateLimiter;
|
|
470
|
+
/**
|
|
471
|
+
* Per-`(topicId, tier)` high-water of the last *applied* notice's `effectiveAt`. A notice at or below the
|
|
472
|
+
* water is a replay / out-of-order frame and is dropped before verification. Updated **only** on an
|
|
473
|
+
* `"applied"` outcome (never on an unverified frame), so a forged notice carrying `effectiveAt = Infinity`
|
|
474
|
+
* cannot poison the water and lock out legitimate notices.
|
|
475
|
+
*
|
|
476
|
+
* **Bounded.** An {@link LruMap} capped at {@link PROMOTE_HIGHWATER_MAX_KEYS} so the retain-forever shape
|
|
477
|
+
* cannot leak on a long-lived node. Unlike the limiter this is *not* attacker-growable (it is written only
|
|
478
|
+
* on an `"applied"` outcome, which needs a verified `≥ minSigs` cohort signature — reads of forged
|
|
479
|
+
* `topicId`s via `.get` create nothing), so it never evicts under legitimate load; the cap is the
|
|
480
|
+
* belt-and-suspenders bound. Evicting an entry is safe: the engine's {@link PromotionLifecycle} is
|
|
481
|
+
* independently idempotent and `effectiveAt`-ordered (`PromotionState.lastEffectiveAt`), so an
|
|
482
|
+
* evicted-then-replayed older notice re-verifies (one bounded, rate-capped `verifyMessage`) and then
|
|
483
|
+
* **no-ops at the engine** rather than (re-)applying. Water absence only *opens* the gate, never closes it.
|
|
484
|
+
*/
|
|
485
|
+
readonly highWater: LruMap<string, number>;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Hard cap on tracked `(topicId, tier)` high-water entries; the least-recently-touched are evicted beyond
|
|
489
|
+
* this. A modest bound is plenty — only verified applies grow the map, so it never evicts under legitimate
|
|
490
|
+
* load — but it caps the otherwise retain-forever shape on a long-lived node.
|
|
491
|
+
*/
|
|
492
|
+
export declare const PROMOTE_HIGHWATER_MAX_KEYS = 8192;
|
|
493
|
+
/** Build the default {@link PromoteGate} from the (optional) anti-DoS rate-limiter config. */
|
|
494
|
+
export declare function createPromoteGate(rateLimiterConfig?: RegisterRateLimiterConfig): PromoteGate;
|
|
495
|
+
/**
|
|
496
|
+
* The slice of a {@link CoordEngine} the inbound notice path needs: the cohort coord the signers should
|
|
497
|
+
* belong to (for verification) and the apply hooks. {@link CoordEngine} satisfies this; tests can pass a
|
|
498
|
+
* minimal stand-in.
|
|
499
|
+
*/
|
|
500
|
+
export interface NoticeApplyTarget {
|
|
501
|
+
readonly servedCoord: RingCoord;
|
|
502
|
+
applyPromotionNotice(notice: PromotionNoticeV1, now: number): void;
|
|
503
|
+
applyDemotionNotice(notice: DemotionNoticeV1, now: number): void;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Decode a `promote`-protocol frame as a {@link PromotionNoticeV1} or {@link DemotionNoticeV1} (try one,
|
|
507
|
+
* then the other), or `undefined` if it is neither. The two shapes are disjoint — a promotion carries
|
|
508
|
+
* `fromTier`/`toTier`, a demotion carries `parentCohortCoord` — so the structural validators cleanly
|
|
509
|
+
* discriminate.
|
|
510
|
+
*/
|
|
511
|
+
export declare function decodeInboundNotice(frame: Uint8Array, maxBytes?: number): InboundNotice | undefined;
|
|
512
|
+
/**
|
|
513
|
+
* Per-coord minimum interval (ms) between membership refetches on the inbound `promote` path. Caps the
|
|
514
|
+
* amplification a flood of forged notices can drive: a stream of verify-misses triggers at most one
|
|
515
|
+
* `source.fetch()` per coord per this window, while a cold cache / membership rotation still re-fetches
|
|
516
|
+
* once it elapses (eventual refetch preserved). 60 s mirrors the anti-DoS rate window.
|
|
517
|
+
*/
|
|
518
|
+
export declare const PROMOTE_REFETCH_MIN_INTERVAL_MS = 60000;
|
|
519
|
+
/**
|
|
520
|
+
* Verify an inbound notice's threshold signature against the cohort `MembershipCertV1` for
|
|
521
|
+
* `target.servedCoord` and, on success, apply it to the target's promotion lifecycle. Returns:
|
|
522
|
+
*
|
|
523
|
+
* - `"dropped"` — no local engine serves the notice's `(topic, tier)` (e.g. a demotion arriving at a
|
|
524
|
+
* parent that does not track the child); nothing to apply to.
|
|
525
|
+
* - `"untrusted"` — the `signers` are not a `≥ minSigs` subset of the cohort cert, or the multisig does
|
|
526
|
+
* not verify (a forged single-signer / short-quorum notice); local state is left unchanged.
|
|
527
|
+
* - `"applied"` — verified and applied.
|
|
528
|
+
*
|
|
529
|
+
* The payload is rebuilt with the canonical `sig/payloads` image the signer used — never re-canonicalized
|
|
530
|
+
* independently. The verifier owns the cert lookup; this function never re-verifies inside the apply step
|
|
531
|
+
* (db-core trusts this gate).
|
|
532
|
+
*
|
|
533
|
+
* **Bounded refetch (anti-amplification).** Both verify calls pass a {@link PROMOTE_REFETCH_MIN_INTERVAL_MS}
|
|
534
|
+
* refetch bound, so a stream of forged notices drives at most **one** membership `source.fetch()` per coord
|
|
535
|
+
* per interval rather than one dial per message. Eventual refetch is preserved (full suppression was
|
|
536
|
+
* rejected: a legitimate sibling-adopt / demotion-to-parent notice whose cohort cert is not yet locally
|
|
537
|
+
* cached must still be able to fetch it once — see `live-tier.spec.ts` test 4). A node that has cached its
|
|
538
|
+
* own cohort cert via `onCertPublished` verifies a sibling-adopt notice from cache with zero fetches; a
|
|
539
|
+
* cold-cache receiver pays one bounded fetch. Per `cohort-topic-promote-handler-verify-amplification`.
|
|
540
|
+
*/
|
|
541
|
+
export declare function verifyAndApplyNotice(inbound: InboundNotice, target: NoticeApplyTarget | undefined, verifier: MembershipVerifier, now: number): Promise<NoticeOutcome>;
|
|
542
|
+
/**
|
|
543
|
+
* Full inbound `promote`-frame pipeline with the anti-abuse gate, exported so it is unit-testable without a
|
|
544
|
+
* live node (`cohort-topic-promote-handler-verify-amplification`). Runs the cheapest checks first — each
|
|
545
|
+
* step strictly cheaper than the next — so a flood of forged frames is shed before any signature / network
|
|
546
|
+
* work:
|
|
547
|
+
*
|
|
548
|
+
* ```
|
|
549
|
+
* decode → per-(peer,topic) rate limit → findServing → effectiveAt high-water → verify+apply
|
|
550
|
+
* ```
|
|
551
|
+
*
|
|
552
|
+
* - **Rate limit** (`gate.rateLimiter`) keys on `(from, topicId)`; an over-rate peer is dropped before the
|
|
553
|
+
* `findServing` map scan and the verify, so a peer cannot amplify junk into verify/network work.
|
|
554
|
+
* - **High-water** (`gate.highWater`, per `(topicId, tier)`) drops a notice whose `effectiveAt` is at or
|
|
555
|
+
* below the last *applied* one — a replay / out-of-order frame — before `verifyMessage`. It is advanced
|
|
556
|
+
* **only** on an `"applied"` outcome, so a forged frame (which never verifies) cannot poison it.
|
|
557
|
+
* - The receiver-side `cohortEpoch` is intentionally **not** gated on: the epoch rotates on every
|
|
558
|
+
* membership change, so a legitimately in-flight notice can briefly carry the prior epoch right after a
|
|
559
|
+
* rotation — making an epoch check a brittle, false-positive-prone filter. The rate limiter + high-water
|
|
560
|
+
* are the load-bearing defenses; the bounded refetch (in {@link verifyAndApplyNotice}) caps the network
|
|
561
|
+
* amplification on the verify itself.
|
|
562
|
+
*
|
|
563
|
+
* `from` is the dialing peer's substrate bytes ({@link peerIdToBytes}); the node handler converts the
|
|
564
|
+
* libp2p `PeerId` before calling. One-way contract: the caller sends no ack regardless of outcome.
|
|
565
|
+
*/
|
|
566
|
+
export declare function handleInboundNotice(frame: Uint8Array, from: Uint8Array, registry: CoordRegistry, verifier: MembershipVerifier, gate: PromoteGate, now: number, maxBytes?: number): Promise<InboundNoticeResult>;
|
|
567
|
+
/**
|
|
568
|
+
* The cohort coords a notice is broadcast to over the `promote` protocol: always the cohort around
|
|
569
|
+
* `servedCoord` (siblings adopt the state); for a demotion, additionally the parent cohort coord (so the
|
|
570
|
+
* parent's `childCohortCount` bookkeeping converges). Pure — exported for testing the fan-out targets.
|
|
571
|
+
*/
|
|
572
|
+
export declare function noticeBroadcastCoords(notice: PromotionNoticeV1 | DemotionNoticeV1, servedCoord: RingCoord): RingCoord[];
|
|
573
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../src/cohort-topic/host.ts"],"names":[],"mappings":"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"}
|