@optimystic/db-core 0.13.5 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/cluster/structs.d.ts +13 -0
- package/dist/src/cluster/structs.d.ts.map +1 -1
- package/dist/src/cohort-topic/addressing.d.ts +53 -0
- package/dist/src/cohort-topic/addressing.d.ts.map +1 -0
- package/dist/src/cohort-topic/addressing.js +95 -0
- package/dist/src/cohort-topic/addressing.js.map +1 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts +105 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts.map +1 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js +197 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js.map +1 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts +50 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts.map +1 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence.js +62 -0
- package/dist/src/cohort-topic/antidos/bootstrap-evidence.js.map +1 -0
- package/dist/src/cohort-topic/antidos/index.d.ts +6 -0
- package/dist/src/cohort-topic/antidos/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/antidos/index.js +6 -0
- package/dist/src/cohort-topic/antidos/index.js.map +1 -0
- package/dist/src/cohort-topic/antidos/rate-limiter.d.ts +95 -0
- package/dist/src/cohort-topic/antidos/rate-limiter.d.ts.map +1 -0
- package/dist/src/cohort-topic/antidos/rate-limiter.js +146 -0
- package/dist/src/cohort-topic/antidos/rate-limiter.js.map +1 -0
- package/dist/src/cohort-topic/antidos/replay-guard.d.ts +37 -0
- package/dist/src/cohort-topic/antidos/replay-guard.d.ts.map +1 -0
- package/dist/src/cohort-topic/antidos/replay-guard.js +78 -0
- package/dist/src/cohort-topic/antidos/replay-guard.js.map +1 -0
- package/dist/src/cohort-topic/antidos/topic-budget.d.ts +50 -0
- package/dist/src/cohort-topic/antidos/topic-budget.d.ts.map +1 -0
- package/dist/src/cohort-topic/antidos/topic-budget.js +95 -0
- package/dist/src/cohort-topic/antidos/topic-budget.js.map +1 -0
- package/dist/src/cohort-topic/antiflood/index.d.ts +3 -0
- package/dist/src/cohort-topic/antiflood/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/antiflood/index.js +3 -0
- package/dist/src/cohort-topic/antiflood/index.js.map +1 -0
- package/dist/src/cohort-topic/antiflood/invariants.d.ts +70 -0
- package/dist/src/cohort-topic/antiflood/invariants.d.ts.map +1 -0
- package/dist/src/cohort-topic/antiflood/invariants.js +86 -0
- package/dist/src/cohort-topic/antiflood/invariants.js.map +1 -0
- package/dist/src/cohort-topic/antiflood/jitter.d.ts +65 -0
- package/dist/src/cohort-topic/antiflood/jitter.d.ts.map +1 -0
- package/dist/src/cohort-topic/antiflood/jitter.js +75 -0
- package/dist/src/cohort-topic/antiflood/jitter.js.map +1 -0
- package/dist/src/cohort-topic/coldstart.d.ts +117 -0
- package/dist/src/cohort-topic/coldstart.d.ts.map +1 -0
- package/dist/src/cohort-topic/coldstart.js +127 -0
- package/dist/src/cohort-topic/coldstart.js.map +1 -0
- package/dist/src/cohort-topic/dmax.d.ts +44 -0
- package/dist/src/cohort-topic/dmax.d.ts.map +1 -0
- package/dist/src/cohort-topic/dmax.js +70 -0
- package/dist/src/cohort-topic/dmax.js.map +1 -0
- package/dist/src/cohort-topic/gossip/bus.d.ts +85 -0
- package/dist/src/cohort-topic/gossip/bus.d.ts.map +1 -0
- package/dist/src/cohort-topic/gossip/bus.js +146 -0
- package/dist/src/cohort-topic/gossip/bus.js.map +1 -0
- package/dist/src/cohort-topic/gossip/index.d.ts +4 -0
- package/dist/src/cohort-topic/gossip/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/gossip/index.js +4 -0
- package/dist/src/cohort-topic/gossip/index.js.map +1 -0
- package/dist/src/cohort-topic/gossip/records.d.ts +12 -0
- package/dist/src/cohort-topic/gossip/records.d.ts.map +1 -0
- package/dist/src/cohort-topic/gossip/records.js +41 -0
- package/dist/src/cohort-topic/gossip/records.js.map +1 -0
- package/dist/src/cohort-topic/gossip/view.d.ts +39 -0
- package/dist/src/cohort-topic/gossip/view.d.ts.map +1 -0
- package/dist/src/cohort-topic/gossip/view.js +30 -0
- package/dist/src/cohort-topic/gossip/view.js.map +1 -0
- package/dist/src/cohort-topic/index.d.ts +21 -0
- package/dist/src/cohort-topic/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/index.js +21 -0
- package/dist/src/cohort-topic/index.js.map +1 -0
- package/dist/src/cohort-topic/load/barometer.d.ts +78 -0
- package/dist/src/cohort-topic/load/barometer.d.ts.map +1 -0
- package/dist/src/cohort-topic/load/barometer.js +93 -0
- package/dist/src/cohort-topic/load/barometer.js.map +1 -0
- package/dist/src/cohort-topic/load/index.d.ts +2 -0
- package/dist/src/cohort-topic/load/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/load/index.js +2 -0
- package/dist/src/cohort-topic/load/index.js.map +1 -0
- package/dist/src/cohort-topic/member-engine.d.ts +134 -0
- package/dist/src/cohort-topic/member-engine.d.ts.map +1 -0
- package/dist/src/cohort-topic/member-engine.js +264 -0
- package/dist/src/cohort-topic/member-engine.js.map +1 -0
- package/dist/src/cohort-topic/membership/index.d.ts +4 -0
- package/dist/src/cohort-topic/membership/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership/index.js +4 -0
- package/dist/src/cohort-topic/membership/index.js.map +1 -0
- package/dist/src/cohort-topic/membership/publisher.d.ts +82 -0
- package/dist/src/cohort-topic/membership/publisher.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership/publisher.js +107 -0
- package/dist/src/cohort-topic/membership/publisher.js.map +1 -0
- package/dist/src/cohort-topic/membership/source.d.ts +31 -0
- package/dist/src/cohort-topic/membership/source.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership/source.js +32 -0
- package/dist/src/cohort-topic/membership/source.js.map +1 -0
- package/dist/src/cohort-topic/membership/verifier.d.ts +96 -0
- package/dist/src/cohort-topic/membership/verifier.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership/verifier.js +250 -0
- package/dist/src/cohort-topic/membership/verifier.js.map +1 -0
- package/dist/src/cohort-topic/ports.d.ts +149 -0
- package/dist/src/cohort-topic/ports.d.ts.map +1 -0
- package/dist/src/cohort-topic/ports.js +25 -0
- package/dist/src/cohort-topic/ports.js.map +1 -0
- package/dist/src/cohort-topic/promotion.d.ts +135 -0
- package/dist/src/cohort-topic/promotion.d.ts.map +1 -0
- package/dist/src/cohort-topic/promotion.js +269 -0
- package/dist/src/cohort-topic/promotion.js.map +1 -0
- package/dist/src/cohort-topic/registration/bytes.d.ts +16 -0
- package/dist/src/cohort-topic/registration/bytes.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/bytes.js +32 -0
- package/dist/src/cohort-topic/registration/bytes.js.map +1 -0
- package/dist/src/cohort-topic/registration/handoff.d.ts +69 -0
- package/dist/src/cohort-topic/registration/handoff.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/handoff.js +98 -0
- package/dist/src/cohort-topic/registration/handoff.js.map +1 -0
- package/dist/src/cohort-topic/registration/index.d.ts +7 -0
- package/dist/src/cohort-topic/registration/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/index.js +7 -0
- package/dist/src/cohort-topic/registration/index.js.map +1 -0
- package/dist/src/cohort-topic/registration/renewal.d.ts +115 -0
- package/dist/src/cohort-topic/registration/renewal.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/renewal.js +306 -0
- package/dist/src/cohort-topic/registration/renewal.js.map +1 -0
- package/dist/src/cohort-topic/registration/sharding.d.ts +31 -0
- package/dist/src/cohort-topic/registration/sharding.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/sharding.js +48 -0
- package/dist/src/cohort-topic/registration/sharding.js.map +1 -0
- package/dist/src/cohort-topic/registration/store.d.ts +13 -0
- package/dist/src/cohort-topic/registration/store.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/store.js +72 -0
- package/dist/src/cohort-topic/registration/store.js.map +1 -0
- package/dist/src/cohort-topic/registration/types.d.ts +71 -0
- package/dist/src/cohort-topic/registration/types.d.ts.map +1 -0
- package/dist/src/cohort-topic/registration/types.js +27 -0
- package/dist/src/cohort-topic/registration/types.js.map +1 -0
- package/dist/src/cohort-topic/ring-hash.d.ts +27 -0
- package/dist/src/cohort-topic/ring-hash.d.ts.map +1 -0
- package/dist/src/cohort-topic/ring-hash.js +45 -0
- package/dist/src/cohort-topic/ring-hash.js.map +1 -0
- package/dist/src/cohort-topic/service.d.ts +157 -0
- package/dist/src/cohort-topic/service.d.ts.map +1 -0
- package/dist/src/cohort-topic/service.js +237 -0
- package/dist/src/cohort-topic/service.js.map +1 -0
- package/dist/src/cohort-topic/sig/index.d.ts +3 -0
- package/dist/src/cohort-topic/sig/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/sig/index.js +3 -0
- package/dist/src/cohort-topic/sig/index.js.map +1 -0
- package/dist/src/cohort-topic/sig/payloads.d.ts +25 -0
- package/dist/src/cohort-topic/sig/payloads.d.ts.map +1 -0
- package/dist/src/cohort-topic/sig/payloads.js +25 -0
- package/dist/src/cohort-topic/sig/payloads.js.map +1 -0
- package/dist/src/cohort-topic/sig/threshold.d.ts +33 -0
- package/dist/src/cohort-topic/sig/threshold.d.ts.map +1 -0
- package/dist/src/cohort-topic/sig/threshold.js +51 -0
- package/dist/src/cohort-topic/sig/threshold.js.map +1 -0
- package/dist/src/cohort-topic/tiers.d.ts +58 -0
- package/dist/src/cohort-topic/tiers.d.ts.map +1 -0
- package/dist/src/cohort-topic/tiers.js +49 -0
- package/dist/src/cohort-topic/tiers.js.map +1 -0
- package/dist/src/cohort-topic/traffic.d.ts +90 -0
- package/dist/src/cohort-topic/traffic.d.ts.map +1 -0
- package/dist/src/cohort-topic/traffic.js +146 -0
- package/dist/src/cohort-topic/traffic.js.map +1 -0
- package/dist/src/cohort-topic/walk.d.ts +123 -0
- package/dist/src/cohort-topic/walk.d.ts.map +1 -0
- package/dist/src/cohort-topic/walk.js +150 -0
- package/dist/src/cohort-topic/walk.js.map +1 -0
- package/dist/src/cohort-topic/willingness.d.ts +123 -0
- package/dist/src/cohort-topic/willingness.d.ts.map +1 -0
- package/dist/src/cohort-topic/willingness.js +143 -0
- package/dist/src/cohort-topic/willingness.js.map +1 -0
- package/dist/src/cohort-topic/wire/codec.d.ts +42 -0
- package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -0
- package/dist/src/cohort-topic/wire/codec.js +163 -0
- package/dist/src/cohort-topic/wire/codec.js.map +1 -0
- package/dist/src/cohort-topic/wire/index.d.ts +6 -0
- package/dist/src/cohort-topic/wire/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/wire/index.js +6 -0
- package/dist/src/cohort-topic/wire/index.js.map +1 -0
- package/dist/src/cohort-topic/wire/payloads.d.ts +38 -0
- package/dist/src/cohort-topic/wire/payloads.d.ts.map +1 -0
- package/dist/src/cohort-topic/wire/payloads.js +102 -0
- package/dist/src/cohort-topic/wire/payloads.js.map +1 -0
- package/dist/src/cohort-topic/wire/types.d.ts +304 -0
- package/dist/src/cohort-topic/wire/types.d.ts.map +1 -0
- package/dist/src/cohort-topic/wire/types.js +16 -0
- package/dist/src/cohort-topic/wire/types.js.map +1 -0
- package/dist/src/cohort-topic/wire/validate.d.ts +25 -0
- package/dist/src/cohort-topic/wire/validate.d.ts.map +1 -0
- package/dist/src/cohort-topic/wire/validate.js +427 -0
- package/dist/src/cohort-topic/wire/validate.js.map +1 -0
- package/dist/src/collection/collection.d.ts +58 -1
- package/dist/src/collection/collection.d.ts.map +1 -1
- package/dist/src/collection/collection.js +76 -0
- package/dist/src/collection/collection.js.map +1 -1
- package/dist/src/collections/tree/tree.d.ts +58 -2
- package/dist/src/collections/tree/tree.d.ts.map +1 -1
- package/dist/src/collections/tree/tree.js +59 -2
- package/dist/src/collections/tree/tree.js.map +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/log/log.d.ts +42 -4
- package/dist/src/log/log.d.ts.map +1 -1
- package/dist/src/log/log.js +71 -3
- package/dist/src/log/log.js.map +1 -1
- package/dist/src/log/struct.d.ts +122 -2
- package/dist/src/log/struct.d.ts.map +1 -1
- package/dist/src/log/struct.js.map +1 -1
- package/dist/src/matchmaking/capability-filter.d.ts +24 -0
- package/dist/src/matchmaking/capability-filter.d.ts.map +1 -0
- package/dist/src/matchmaking/capability-filter.js +37 -0
- package/dist/src/matchmaking/capability-filter.js.map +1 -0
- package/dist/src/matchmaking/config.d.ts +77 -0
- package/dist/src/matchmaking/config.d.ts.map +1 -0
- package/dist/src/matchmaking/config.js +69 -0
- package/dist/src/matchmaking/config.js.map +1 -0
- package/dist/src/matchmaking/index.d.ts +21 -0
- package/dist/src/matchmaking/index.d.ts.map +1 -0
- package/dist/src/matchmaking/index.js +21 -0
- package/dist/src/matchmaking/index.js.map +1 -0
- package/dist/src/matchmaking/multi-cohort-seeker.d.ts +133 -0
- package/dist/src/matchmaking/multi-cohort-seeker.d.ts.map +1 -0
- package/dist/src/matchmaking/multi-cohort-seeker.js +142 -0
- package/dist/src/matchmaking/multi-cohort-seeker.js.map +1 -0
- package/dist/src/matchmaking/provider.d.ts +70 -0
- package/dist/src/matchmaking/provider.d.ts.map +1 -0
- package/dist/src/matchmaking/provider.js +93 -0
- package/dist/src/matchmaking/provider.js.map +1 -0
- package/dist/src/matchmaking/query-eval.d.ts +53 -0
- package/dist/src/matchmaking/query-eval.d.ts.map +1 -0
- package/dist/src/matchmaking/query-eval.js +69 -0
- package/dist/src/matchmaking/query-eval.js.map +1 -0
- package/dist/src/matchmaking/seeker-walk.d.ts +95 -0
- package/dist/src/matchmaking/seeker-walk.d.ts.map +1 -0
- package/dist/src/matchmaking/seeker-walk.js +75 -0
- package/dist/src/matchmaking/seeker-walk.js.map +1 -0
- package/dist/src/matchmaking/seeker.d.ts +51 -0
- package/dist/src/matchmaking/seeker.d.ts.map +1 -0
- package/dist/src/matchmaking/seeker.js +62 -0
- package/dist/src/matchmaking/seeker.js.map +1 -0
- package/dist/src/matchmaking/topic-anchor.d.ts +54 -0
- package/dist/src/matchmaking/topic-anchor.d.ts.map +1 -0
- package/dist/src/matchmaking/topic-anchor.js +67 -0
- package/dist/src/matchmaking/topic-anchor.js.map +1 -0
- package/dist/src/matchmaking/voting-quorum.d.ts +233 -0
- package/dist/src/matchmaking/voting-quorum.d.ts.map +1 -0
- package/dist/src/matchmaking/voting-quorum.js +238 -0
- package/dist/src/matchmaking/voting-quorum.js.map +1 -0
- package/dist/src/matchmaking/wire.d.ts +259 -0
- package/dist/src/matchmaking/wire.d.ts.map +1 -0
- package/dist/src/matchmaking/wire.js +484 -0
- package/dist/src/matchmaking/wire.js.map +1 -0
- package/dist/src/network/i-repo.d.ts +9 -0
- package/dist/src/network/i-repo.d.ts.map +1 -1
- package/dist/src/network/repo-protocol.d.ts +3 -1
- package/dist/src/network/repo-protocol.d.ts.map +1 -1
- package/dist/src/network/struct.d.ts +23 -1
- package/dist/src/network/struct.d.ts.map +1 -1
- package/dist/src/reactivity/backfill.d.ts +118 -0
- package/dist/src/reactivity/backfill.d.ts.map +1 -0
- package/dist/src/reactivity/backfill.js +137 -0
- package/dist/src/reactivity/backfill.js.map +1 -0
- package/dist/src/reactivity/backpressure.d.ts +99 -0
- package/dist/src/reactivity/backpressure.d.ts.map +1 -0
- package/dist/src/reactivity/backpressure.js +153 -0
- package/dist/src/reactivity/backpressure.js.map +1 -0
- package/dist/src/reactivity/checkpoint.d.ts +165 -0
- package/dist/src/reactivity/checkpoint.d.ts.map +1 -0
- package/dist/src/reactivity/checkpoint.js +232 -0
- package/dist/src/reactivity/checkpoint.js.map +1 -0
- package/dist/src/reactivity/config.d.ts +131 -0
- package/dist/src/reactivity/config.d.ts.map +1 -0
- package/dist/src/reactivity/config.js +135 -0
- package/dist/src/reactivity/config.js.map +1 -0
- package/dist/src/reactivity/dedupe.d.ts +51 -0
- package/dist/src/reactivity/dedupe.d.ts.map +1 -0
- package/dist/src/reactivity/dedupe.js +90 -0
- package/dist/src/reactivity/dedupe.js.map +1 -0
- package/dist/src/reactivity/forwarder.d.ts +50 -0
- package/dist/src/reactivity/forwarder.d.ts.map +1 -0
- package/dist/src/reactivity/forwarder.js +52 -0
- package/dist/src/reactivity/forwarder.js.map +1 -0
- package/dist/src/reactivity/index.d.ts +34 -0
- package/dist/src/reactivity/index.d.ts.map +1 -0
- package/dist/src/reactivity/index.js +34 -0
- package/dist/src/reactivity/index.js.map +1 -0
- package/dist/src/reactivity/notification.d.ts +72 -0
- package/dist/src/reactivity/notification.d.ts.map +1 -0
- package/dist/src/reactivity/notification.js +92 -0
- package/dist/src/reactivity/notification.js.map +1 -0
- package/dist/src/reactivity/policy.d.ts +59 -0
- package/dist/src/reactivity/policy.d.ts.map +1 -0
- package/dist/src/reactivity/policy.js +64 -0
- package/dist/src/reactivity/policy.js.map +1 -0
- package/dist/src/reactivity/push-state.d.ts +140 -0
- package/dist/src/reactivity/push-state.d.ts.map +1 -0
- package/dist/src/reactivity/push-state.js +270 -0
- package/dist/src/reactivity/push-state.js.map +1 -0
- package/dist/src/reactivity/recover.d.ts +75 -0
- package/dist/src/reactivity/recover.d.ts.map +1 -0
- package/dist/src/reactivity/recover.js +105 -0
- package/dist/src/reactivity/recover.js.map +1 -0
- package/dist/src/reactivity/replay-buffer.d.ts +57 -0
- package/dist/src/reactivity/replay-buffer.d.ts.map +1 -0
- package/dist/src/reactivity/replay-buffer.js +88 -0
- package/dist/src/reactivity/replay-buffer.js.map +1 -0
- package/dist/src/reactivity/resume.d.ts +214 -0
- package/dist/src/reactivity/resume.d.ts.map +1 -0
- package/dist/src/reactivity/resume.js +358 -0
- package/dist/src/reactivity/resume.js.map +1 -0
- package/dist/src/reactivity/rotation.d.ts +283 -0
- package/dist/src/reactivity/rotation.d.ts.map +1 -0
- package/dist/src/reactivity/rotation.js +265 -0
- package/dist/src/reactivity/rotation.js.map +1 -0
- package/dist/src/reactivity/subscriber.d.ts +66 -0
- package/dist/src/reactivity/subscriber.d.ts.map +1 -0
- package/dist/src/reactivity/subscriber.js +75 -0
- package/dist/src/reactivity/subscriber.js.map +1 -0
- package/dist/src/reactivity/subscription.d.ts +52 -0
- package/dist/src/reactivity/subscription.d.ts.map +1 -0
- package/dist/src/reactivity/subscription.js +28 -0
- package/dist/src/reactivity/subscription.js.map +1 -0
- package/dist/src/reactivity/topic-anchor.d.ts +46 -0
- package/dist/src/reactivity/topic-anchor.d.ts.map +1 -0
- package/dist/src/reactivity/topic-anchor.js +61 -0
- package/dist/src/reactivity/topic-anchor.js.map +1 -0
- package/dist/src/reactivity/verify.d.ts +41 -0
- package/dist/src/reactivity/verify.d.ts.map +1 -0
- package/dist/src/reactivity/verify.js +48 -0
- package/dist/src/reactivity/verify.js.map +1 -0
- package/dist/src/reactivity/wire-validate.d.ts +28 -0
- package/dist/src/reactivity/wire-validate.d.ts.map +1 -0
- package/dist/src/reactivity/wire-validate.js +79 -0
- package/dist/src/reactivity/wire-validate.js.map +1 -0
- package/dist/src/reactivity/wire.d.ts +102 -0
- package/dist/src/reactivity/wire.d.ts.map +1 -0
- package/dist/src/reactivity/wire.js +129 -0
- package/dist/src/reactivity/wire.js.map +1 -0
- package/dist/src/transaction/coordinator.d.ts +9 -5
- package/dist/src/transaction/coordinator.d.ts.map +1 -1
- package/dist/src/transaction/coordinator.js +48 -25
- package/dist/src/transaction/coordinator.js.map +1 -1
- package/dist/src/transactor/change-notifier.d.ts +74 -0
- package/dist/src/transactor/change-notifier.d.ts.map +1 -0
- package/dist/src/transactor/change-notifier.js +4 -0
- package/dist/src/transactor/change-notifier.js.map +1 -0
- package/dist/src/transactor/index.d.ts +1 -0
- package/dist/src/transactor/index.d.ts.map +1 -1
- package/dist/src/transactor/index.js +1 -0
- package/dist/src/transactor/index.js.map +1 -1
- package/dist/src/transactor/network-transactor.d.ts +34 -2
- package/dist/src/transactor/network-transactor.d.ts.map +1 -1
- package/dist/src/transactor/network-transactor.js +113 -13
- package/dist/src/transactor/network-transactor.js.map +1 -1
- package/package.json +2 -2
- package/src/cluster/structs.ts +13 -0
- package/src/cohort-topic/addressing.ts +112 -0
- package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +253 -0
- package/src/cohort-topic/antidos/bootstrap-evidence.ts +94 -0
- package/src/cohort-topic/antidos/index.ts +5 -0
- package/src/cohort-topic/antidos/rate-limiter.ts +210 -0
- package/src/cohort-topic/antidos/replay-guard.ts +109 -0
- package/src/cohort-topic/antidos/topic-budget.ts +145 -0
- package/src/cohort-topic/antiflood/index.ts +2 -0
- package/src/cohort-topic/antiflood/invariants.ts +108 -0
- package/src/cohort-topic/antiflood/jitter.ts +117 -0
- package/src/cohort-topic/coldstart.ts +204 -0
- package/src/cohort-topic/dmax.ts +88 -0
- package/src/cohort-topic/gossip/bus.ts +217 -0
- package/src/cohort-topic/gossip/index.ts +3 -0
- package/src/cohort-topic/gossip/records.ts +45 -0
- package/src/cohort-topic/gossip/view.ts +66 -0
- package/src/cohort-topic/index.ts +20 -0
- package/src/cohort-topic/load/barometer.ts +134 -0
- package/src/cohort-topic/load/index.ts +1 -0
- package/src/cohort-topic/member-engine.ts +409 -0
- package/src/cohort-topic/membership/index.ts +3 -0
- package/src/cohort-topic/membership/publisher.ts +171 -0
- package/src/cohort-topic/membership/source.ts +41 -0
- package/src/cohort-topic/membership/verifier.ts +345 -0
- package/src/cohort-topic/ports.ts +157 -0
- package/src/cohort-topic/promotion.ts +384 -0
- package/src/cohort-topic/registration/bytes.ts +37 -0
- package/src/cohort-topic/registration/handoff.ts +154 -0
- package/src/cohort-topic/registration/index.ts +6 -0
- package/src/cohort-topic/registration/renewal.ts +423 -0
- package/src/cohort-topic/registration/sharding.ts +61 -0
- package/src/cohort-topic/registration/store.ts +81 -0
- package/src/cohort-topic/registration/types.ts +76 -0
- package/src/cohort-topic/ring-hash.ts +50 -0
- package/src/cohort-topic/service.ts +390 -0
- package/src/cohort-topic/sig/index.ts +2 -0
- package/src/cohort-topic/sig/payloads.ts +39 -0
- package/src/cohort-topic/sig/threshold.ts +64 -0
- package/src/cohort-topic/tiers.ts +74 -0
- package/src/cohort-topic/traffic.ts +211 -0
- package/src/cohort-topic/walk.ts +255 -0
- package/src/cohort-topic/willingness.ts +237 -0
- package/src/cohort-topic/wire/codec.ts +204 -0
- package/src/cohort-topic/wire/index.ts +16 -0
- package/src/cohort-topic/wire/payloads.ts +117 -0
- package/src/cohort-topic/wire/types.ts +343 -0
- package/src/cohort-topic/wire/validate.ts +478 -0
- package/src/collection/collection.ts +93 -1
- package/src/collections/tree/tree.ts +84 -3
- package/src/index.ts +3 -0
- package/src/log/log.ts +86 -7
- package/src/log/struct.ts +126 -2
- package/src/matchmaking/capability-filter.ts +45 -0
- package/src/matchmaking/config.ts +98 -0
- package/src/matchmaking/index.ts +21 -0
- package/src/matchmaking/multi-cohort-seeker.ts +234 -0
- package/src/matchmaking/provider.ts +123 -0
- package/src/matchmaking/query-eval.ts +105 -0
- package/src/matchmaking/seeker-walk.ts +127 -0
- package/src/matchmaking/seeker.ts +86 -0
- package/src/matchmaking/topic-anchor.ts +90 -0
- package/src/matchmaking/voting-quorum.ts +394 -0
- package/src/matchmaking/wire.ts +680 -0
- package/src/network/i-repo.ts +9 -0
- package/src/network/repo-protocol.ts +3 -2
- package/src/network/struct.ts +24 -1
- package/src/reactivity/backfill.ts +220 -0
- package/src/reactivity/backpressure.ts +191 -0
- package/src/reactivity/checkpoint.ts +308 -0
- package/src/reactivity/config.ts +172 -0
- package/src/reactivity/dedupe.ts +132 -0
- package/src/reactivity/forwarder.ts +87 -0
- package/src/reactivity/index.ts +34 -0
- package/src/reactivity/notification.ts +123 -0
- package/src/reactivity/policy.ts +79 -0
- package/src/reactivity/push-state.ts +343 -0
- package/src/reactivity/recover.ts +153 -0
- package/src/reactivity/replay-buffer.ts +141 -0
- package/src/reactivity/resume.ts +549 -0
- package/src/reactivity/rotation.ts +415 -0
- package/src/reactivity/subscriber.ts +132 -0
- package/src/reactivity/subscription.ts +66 -0
- package/src/reactivity/topic-anchor.ts +71 -0
- package/src/reactivity/verify.ts +73 -0
- package/src/reactivity/wire-validate.ts +87 -0
- package/src/reactivity/wire.ts +224 -0
- package/src/transaction/coordinator.ts +53 -27
- package/src/transactor/change-notifier.ts +80 -0
- package/src/transactor/index.ts +1 -0
- package/src/transactor/network-transactor.ts +133 -15
|
@@ -1,14 +1,33 @@
|
|
|
1
|
-
import { Collection, type CollectionInitOptions, type CollectionId } from "../../collection/index.js";
|
|
1
|
+
import { Collection, type CollectionInitOptions, type CollectionId, type CollectionSnapshot } from "../../collection/index.js";
|
|
2
2
|
import type { ITransactor, BlockId, BlockStore, IBlock } from "../../index.js";
|
|
3
3
|
import { BTree, type Path, type KeyRange } from "../../btree/index.js";
|
|
4
4
|
import { CollectionTrunk } from "./collection-trunk.js";
|
|
5
5
|
import { TreeHeaderBlockType, type TreeReplaceAction } from "./struct.js";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Read-only surface of a tree: every navigation/lookup method a reader needs, with
|
|
9
|
+
* none of the mutation (stage/sync) or network-refresh (update) entry points. Both
|
|
10
|
+
* the live {@link Tree} and the committed view returned by {@link Tree.readView}
|
|
11
|
+
* structurally satisfy this, so a consumer can read through either uniformly.
|
|
12
|
+
*/
|
|
13
|
+
export interface TreeReadView<TKey, TEntry> {
|
|
14
|
+
first(): Promise<Path<TKey, TEntry>>;
|
|
15
|
+
find(key: TKey): Promise<Path<TKey, TEntry>>;
|
|
16
|
+
get(key: TKey): Promise<TEntry | undefined>;
|
|
17
|
+
at(path: Path<TKey, TEntry>): TEntry | undefined;
|
|
18
|
+
range(range: KeyRange<TKey>): AsyncIterableIterator<Path<TKey, TEntry>>;
|
|
19
|
+
ascending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>>;
|
|
20
|
+
isValid(path: Path<TKey, TEntry>): boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class Tree<TKey, TEntry> implements TreeReadView<TKey, TEntry> {
|
|
8
24
|
|
|
9
25
|
private constructor(
|
|
10
26
|
private readonly collection: Collection<TreeReplaceAction<TKey, TEntry>>,
|
|
11
27
|
private readonly btree: BTree<TKey, TEntry>,
|
|
28
|
+
/** Captured so {@link readView} can rebuild a BTree over a committed tracker. */
|
|
29
|
+
private readonly keyFromEntry: (entry: TEntry) => TKey,
|
|
30
|
+
private readonly compare: (a: TKey, b: TKey) => number,
|
|
12
31
|
) {
|
|
13
32
|
}
|
|
14
33
|
|
|
@@ -48,7 +67,7 @@ export class Tree<TKey, TEntry> {
|
|
|
48
67
|
|
|
49
68
|
const collection = await Collection.createOrOpen<TreeReplaceAction<TKey, TEntry>>(network, id, init);
|
|
50
69
|
btree = btree ?? new BTree<TKey, TEntry>(collection.tracker, new CollectionTrunk(collection.tracker, collection.id), keyFromEntry, compare);
|
|
51
|
-
return new Tree<TKey, TEntry>(collection, btree);
|
|
70
|
+
return new Tree<TKey, TEntry>(collection, btree, keyFromEntry, compare);
|
|
52
71
|
}
|
|
53
72
|
|
|
54
73
|
async replace(data: TreeReplaceAction<TKey, TEntry>): Promise<void> {
|
|
@@ -56,6 +75,68 @@ export class Tree<TKey, TEntry> {
|
|
|
56
75
|
await this.collection.updateAndSync();
|
|
57
76
|
}
|
|
58
77
|
|
|
78
|
+
/** Stage a mutation into the collection's tracker WITHOUT flushing it to the
|
|
79
|
+
* transactor. Reads through this same Tree instance see the staged change;
|
|
80
|
+
* call {@link sync} to persist it, or {@link snapshot}/{@link restore} to drop it. This
|
|
81
|
+
* is the deferred counterpart to {@link replace}, which stages and flushes in
|
|
82
|
+
* one step — use {@link stage} when the persist/discard decision belongs to a
|
|
83
|
+
* surrounding transaction's commit/rollback. */
|
|
84
|
+
async stage(data: TreeReplaceAction<TKey, TEntry>): Promise<void> {
|
|
85
|
+
await this.collection.act({ type: "replace", data });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Flush all staged (and any other pending) changes to the transactor.
|
|
89
|
+
* Equivalent to the flush half of {@link replace}. */
|
|
90
|
+
async sync(): Promise<void> {
|
|
91
|
+
await this.collection.updateAndSync();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Capture the current staged state so it can be restored via {@link restore}.
|
|
95
|
+
* Take this BEFORE staging a unit of work that may be rolled back. The snapshot
|
|
96
|
+
* is opaque; pass the exact value back to {@link restore}. */
|
|
97
|
+
snapshot(): CollectionSnapshot<TreeReplaceAction<TKey, TEntry>> {
|
|
98
|
+
return this.collection.snapshotPending();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Restore the staged state captured by {@link snapshot}, discarding mutations
|
|
102
|
+
* staged since. Counterpart to {@link stage} for transaction rollback —
|
|
103
|
+
* preserves a never-synced collection's header/root rather than wiping it. */
|
|
104
|
+
restore(snapshot: CollectionSnapshot<TreeReplaceAction<TKey, TEntry>>): void {
|
|
105
|
+
this.collection.restorePending(snapshot);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Build a read-only view of this tree as captured by an earlier {@link snapshot}
|
|
109
|
+
* — typically the pre-transaction state recorded before any DML was staged. The
|
|
110
|
+
* view reads through a FRESH tracker seeded with the snapshot's transforms over
|
|
111
|
+
* the SAME committed source cache, so it observes exactly the snapshot's state:
|
|
112
|
+
* it never sees mutations staged into the live tree after the snapshot, and it
|
|
113
|
+
* does not disturb the live tree (reads are latch-free and tracker-isolated). This
|
|
114
|
+
* is how a `committed.*` scan reads the pre-transaction snapshot while the live
|
|
115
|
+
* tree still holds this transaction's in-flight inserts.
|
|
116
|
+
*
|
|
117
|
+
* `snapshot` is the opaque value returned by {@link snapshot}; pass it back
|
|
118
|
+
* verbatim. */
|
|
119
|
+
readView(snapshot: CollectionSnapshot<TreeReplaceAction<TKey, TEntry>>): TreeReadView<TKey, TEntry> {
|
|
120
|
+
const tracker = this.collection.createReadTracker(snapshot.transforms);
|
|
121
|
+
return new BTree<TKey, TEntry>(
|
|
122
|
+
tracker,
|
|
123
|
+
new CollectionTrunk(tracker, this.collection.id),
|
|
124
|
+
this.keyFromEntry,
|
|
125
|
+
this.compare,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** The underlying {@link Collection} this tree stages mutations into.
|
|
130
|
+
*
|
|
131
|
+
* Exposed (package-internal intent) so a transaction coordinator can register
|
|
132
|
+
* and read the very tracker this tree mutates: session-mode commit reads
|
|
133
|
+
* `collection.tracker.transforms` directly, so the coordinator's collection
|
|
134
|
+
* map must hold the same instance the tree stages into. Prefer this accessor
|
|
135
|
+
* over reaching through `tree['collection']`. */
|
|
136
|
+
getCollection(): Collection<TreeReplaceAction<TKey, TEntry>> {
|
|
137
|
+
return this.collection;
|
|
138
|
+
}
|
|
139
|
+
|
|
59
140
|
/**
|
|
60
141
|
* Update the local state from the network.
|
|
61
142
|
* Call this before reading to ensure you have the latest data.
|
package/src/index.ts
CHANGED
|
@@ -2,10 +2,13 @@ export * from "./blocks/index.js";
|
|
|
2
2
|
export * from "./btree/index.js";
|
|
3
3
|
export * from "./chain/index.js";
|
|
4
4
|
export * from "./cluster/index.js";
|
|
5
|
+
export * from "./cohort-topic/index.js";
|
|
5
6
|
export * from "./collection/index.js";
|
|
6
7
|
export * from "./collections/index.js";
|
|
7
8
|
export * from "./log/index.js";
|
|
9
|
+
export * from "./matchmaking/index.js";
|
|
8
10
|
export * from "./network/index.js";
|
|
11
|
+
export * from "./reactivity/index.js";
|
|
9
12
|
export * from "./transaction/index.js";
|
|
10
13
|
export * from "./transactor/index.js";
|
|
11
14
|
export * from "./transform/index.js";
|
package/src/log/log.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { sha256 } from 'multiformats/hashes/sha2'
|
|
2
2
|
import { Chain, entryAt } from "../index.js";
|
|
3
3
|
import { nameof } from "../utility/nameof.js";
|
|
4
|
-
import type { IBlock, BlockId, ActionId, CollectionId, ChainPath, ActionRev, ActionContext, ChainInitOptions, BlockStore } from "../index.js";
|
|
4
|
+
import type { IBlock, BlockId, ActionId, CollectionId, ChainPath, ActionRev, ActionContext, ChainInitOptions, BlockStore, ReadDependency } from "../index.js";
|
|
5
5
|
import type { ChainDataNode } from '../chain/chain-nodes.js';
|
|
6
|
-
import type { LogEntry, ActionEntry } from "./index.js";
|
|
6
|
+
import type { LogEntry, ActionEntry, DisputeResolutionProof, InvalidationEntry, RevertedBlock } from "./index.js";
|
|
7
7
|
import { LogDataBlockType, LogHeaderBlockType } from "./index.js";
|
|
8
8
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
9
9
|
import type { GetFromResult } from './struct.js';
|
|
@@ -41,9 +41,19 @@ export class Log<TAction> {
|
|
|
41
41
|
}));
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Adds a new action entry to the log.
|
|
46
|
+
*
|
|
47
|
+
* `reads` is the transaction's `(blockId, revision)` read set, persisted on the entry so the
|
|
48
|
+
* invalidation cascade can later discover this action's read-dependents (see
|
|
49
|
+
* {@link ActionEntry.reads}). Omit it (or pass `undefined`) on the low-level direct-commit path
|
|
50
|
+
* that carries no `Transaction`; the cascade then treats the entry as an unknown dependency.
|
|
51
|
+
*/
|
|
52
|
+
async addActions(actions: TAction[], actionId: ActionId, rev: number, getBlockIds: () => BlockId[], collectionIds: CollectionId[] = [], reads?: ReadDependency[], timestamp: number = Date.now()) {
|
|
53
|
+
const action = reads !== undefined
|
|
54
|
+
? { actionId, actions, blockIds: [], collectionIds, reads }
|
|
55
|
+
: { actionId, actions, blockIds: [], collectionIds };
|
|
56
|
+
const entry = { timestamp, rev, action } as LogEntry<TAction>;
|
|
47
57
|
const tailPath = await this.chain.add(entry);
|
|
48
58
|
const entryWithBlockIds = { ...entry, action: { ...entry.action!, blockIds: getBlockIds() } };
|
|
49
59
|
this.chain.updateAt(tailPath, entryWithBlockIds);
|
|
@@ -57,6 +67,70 @@ export class Log<TAction> {
|
|
|
57
67
|
return { entry, tailPath };
|
|
58
68
|
}
|
|
59
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Appends a compensating invalidation entry that reverses a previously-committed action proven
|
|
72
|
+
* invalid by dispute. The committed history is never rewritten — this is a new, append-only,
|
|
73
|
+
* prior-hash-linked entry, recoverable on sync exactly like a commit. The caller has already
|
|
74
|
+
* verified `resolution` is a challenger-wins certificate and computed the per-block `reverted`
|
|
75
|
+
* targets (the new revisions restoring the as-if-`T_inv`-absent content).
|
|
76
|
+
*/
|
|
77
|
+
async addInvalidation(
|
|
78
|
+
invalidatedActionId: ActionId,
|
|
79
|
+
invalidatedRev: number,
|
|
80
|
+
resolution: DisputeResolutionProof,
|
|
81
|
+
reverted: ReadonlyArray<RevertedBlock>,
|
|
82
|
+
rev: number,
|
|
83
|
+
cascadeRoot?: ActionId,
|
|
84
|
+
timestamp: number = Date.now()
|
|
85
|
+
) {
|
|
86
|
+
const invalidation: InvalidationEntry = cascadeRoot !== undefined
|
|
87
|
+
? { invalidatedActionId, invalidatedRev, resolution, reverted, cascadeRoot }
|
|
88
|
+
: { invalidatedActionId, invalidatedRev, resolution, reverted };
|
|
89
|
+
const entry = { timestamp, rev, invalidation } as LogEntry<TAction>;
|
|
90
|
+
const tailPath = await this.chain.add(entry);
|
|
91
|
+
return { entry, tailPath };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Finds the most recent invalidation entry that reverses the given committed action, if any.
|
|
96
|
+
* This is the durable source of truth for `committed-invalidated` status — once the entry has
|
|
97
|
+
* landed in the log, the reversal is recoverable on sync independent of any in-memory cache.
|
|
98
|
+
* Scans newest→oldest (O(n) over the chain, matching {@link getFrom}); returns the first match.
|
|
99
|
+
*/
|
|
100
|
+
async findInvalidation(invalidatedActionId: ActionId): Promise<InvalidationEntry | undefined> {
|
|
101
|
+
for await (const path of this.chain.select(undefined, false)) {
|
|
102
|
+
const invalidation = entryAt<LogEntry<TAction>>(path)!.invalidation;
|
|
103
|
+
if (invalidation && invalidation.invalidatedActionId === invalidatedActionId) {
|
|
104
|
+
return invalidation;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns the invalidation entries appended after `startRev` (exclusive), newest-first. Used by
|
|
112
|
+
* {@link import("../collection/collection.js").Collection} on `update` to discover reversals that
|
|
113
|
+
* landed since the client last synced: a client holding a result derived from now-reverted content
|
|
114
|
+
* drops it and replays against the reverted base — the same "your base moved, re-sync and retry"
|
|
115
|
+
* path a stale read triggers (`docs/right-is-right.md` §Client notification). Unlike {@link getFrom}
|
|
116
|
+
* (which skips invalidation entries — they are not pending/committed actions), this surfaces exactly
|
|
117
|
+
* the invalidations. Scans newest→oldest and stops once at/below `startRev` (revs are monotonic), so
|
|
118
|
+
* the walk is bounded to the unsynced tail.
|
|
119
|
+
*/
|
|
120
|
+
async getInvalidationsFrom(startRev: number | undefined): Promise<InvalidationEntry[]> {
|
|
121
|
+
const invalidations: InvalidationEntry[] = [];
|
|
122
|
+
for await (const path of this.chain.select(undefined, false)) {
|
|
123
|
+
const entry = entryAt<LogEntry<TAction>>(path)!;
|
|
124
|
+
if (startRev !== undefined && entry.rev <= startRev) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
if (entry.invalidation) {
|
|
128
|
+
invalidations.push(entry.invalidation);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return invalidations;
|
|
132
|
+
}
|
|
133
|
+
|
|
60
134
|
/** Gets the action context of the log. */
|
|
61
135
|
async getActionContext(): Promise<ActionContext | undefined> {
|
|
62
136
|
const tailPath = await this.chain.getTail();
|
|
@@ -90,9 +164,14 @@ export class Log<TAction> {
|
|
|
90
164
|
pendings.unshift(...entry.checkpoint.pendings);
|
|
91
165
|
break;
|
|
92
166
|
}
|
|
93
|
-
|
|
167
|
+
// Invalidation entries take a rev slot but are not pending actions — skip them in
|
|
168
|
+
// the committed/pending set (the reversal is surfaced via findInvalidation instead).
|
|
169
|
+
if (!entry.action) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
pendings.unshift({ actionId: entry.action.actionId, rev: entry.rev });
|
|
94
173
|
if (startRev !== undefined && entry.rev > startRev) {
|
|
95
|
-
entries.unshift(entry.action
|
|
174
|
+
entries.unshift(entry.action);
|
|
96
175
|
} // Can't stop at rev, because we need to collect all pending actions for the context
|
|
97
176
|
}
|
|
98
177
|
// Continue stepping past the checkpoint until the given rev is reached
|
package/src/log/struct.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BlockId, CollectionId, ActionContext, ActionId, ActionRev } from "../index.js";
|
|
1
|
+
import type { BlockId, CollectionId, ActionContext, ActionId, ActionRev, ReadDependency } from "../index.js";
|
|
2
2
|
|
|
3
|
-
/** A log entry -
|
|
3
|
+
/** A log entry - an action, a checkpoint, or an invalidation */
|
|
4
4
|
export type LogEntry<TAction> = {
|
|
5
5
|
/** Linux timestamp of the entry */
|
|
6
6
|
readonly timestamp: number;
|
|
@@ -8,6 +8,8 @@ export type LogEntry<TAction> = {
|
|
|
8
8
|
readonly rev: number;
|
|
9
9
|
readonly action?: ActionEntry<TAction>;
|
|
10
10
|
readonly checkpoint?: CheckpointEntry;
|
|
11
|
+
/** A compensating entry that reverses a previously-committed action proven invalid by dispute. */
|
|
12
|
+
readonly invalidation?: InvalidationEntry;
|
|
11
13
|
};
|
|
12
14
|
|
|
13
15
|
/** An action entry represents a unit of work that is atomic */
|
|
@@ -20,6 +22,128 @@ export type ActionEntry<TAction> = {
|
|
|
20
22
|
blockIds: BlockId[]; // NOTE: this is updated after being generated to include the log-related block transforms
|
|
21
23
|
/** Other collection ids affected by the action - this action is conditional on successful commit in all of these collections */
|
|
22
24
|
readonly collectionIds?: CollectionId[];
|
|
25
|
+
/**
|
|
26
|
+
* The `(blockId, revision)` reads this transaction observed during execution — the same
|
|
27
|
+
* read set the {@link Transaction} carried in its PEND request (see `Transaction.reads`).
|
|
28
|
+
*
|
|
29
|
+
* Persisted so a later invalidation cascade can discover this action's read-dependents:
|
|
30
|
+
* a committed action is a read-dependent of an invalidated one iff its read set contains a
|
|
31
|
+
* `(blockId, revision)` that the invalidated action produced.
|
|
32
|
+
*
|
|
33
|
+
* **Format / back-compat:** added by the invalidation-cascade work (ActionEntry v2). An entry
|
|
34
|
+
* written before this field existed (or by a path that does not carry a `Transaction`, e.g. the
|
|
35
|
+
* low-level `Collection.sync` direct-commit) has `reads === undefined` — treated by the cascade
|
|
36
|
+
* as an *unknown dependency* (conservatively re-evaluated, never silently assumed independent).
|
|
37
|
+
* `reads === []` is distinct: a transaction that genuinely read nothing.
|
|
38
|
+
*/
|
|
39
|
+
readonly reads?: ReadDependency[];
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* One arbitrator's signed verdict — the minimal subset of a dispute vote needed to re-verify
|
|
44
|
+
* it independently. The Ed25519 public key that verifies {@link signature} is embedded in
|
|
45
|
+
* {@link arbitratorPeerId} (a libp2p Ed25519 peer id).
|
|
46
|
+
*
|
|
47
|
+
* The signed payload is **target- and arbitrator-set-bound** (v3):
|
|
48
|
+
* `utf8(`v3:${disputeId}:${vote}:${computedHash}:${targetHash}:${setHash}`)`, where
|
|
49
|
+
* - `targetHash = hashString(`${messageHash}|${invalidatedActionId}|${sortedBlockIds.join(',')}`)`
|
|
50
|
+
* commits the vote to the *specific* transaction being reversed (#2), and
|
|
51
|
+
* - `setHash = hashString(sortedArbitratorSet.join(','))` commits it to the *legitimately-selected
|
|
52
|
+
* arbitrator set* (#1) carried on {@link DisputeResolutionProof.arbitratorSet}.
|
|
53
|
+
*
|
|
54
|
+
* A verifier recomputes both digests from the proof plus the apply-path target, so a genuine vote can
|
|
55
|
+
* neither be replayed against an unrelated transaction nor presented under a swapped cohort. v1/v2
|
|
56
|
+
* (un-set-bound) votes are rejected, not accepted-by-default; the {@link version} marker is required.
|
|
57
|
+
*/
|
|
58
|
+
export type ArbitrationVoteProof = {
|
|
59
|
+
/** Wire-format version of the signed payload. Only `'v3'` is accepted; absent/unrecognized → rejected. */
|
|
60
|
+
readonly version: 'v3';
|
|
61
|
+
/** Peer id of the arbitrator; its embedded Ed25519 public key verifies {@link signature}. */
|
|
62
|
+
readonly arbitratorPeerId: string;
|
|
63
|
+
/** The arbitrator's verdict. */
|
|
64
|
+
readonly vote: 'agree-with-challenger' | 'agree-with-majority' | 'inconclusive';
|
|
65
|
+
/** The operations hash the arbitrator computed (part of the signed payload). */
|
|
66
|
+
readonly computedHash: string;
|
|
67
|
+
/** Base64url-encoded Ed25519 signature over `v3:${disputeId}:${vote}:${computedHash}:${targetHash}:${setHash}`. */
|
|
68
|
+
readonly signature: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The authoritative, independently-verifiable subset of a dispute resolution that proves a
|
|
73
|
+
* committed transaction invalid. Carried inside an {@link InvalidationEntry}.
|
|
74
|
+
*
|
|
75
|
+
* Defined in db-core (the log layer) deliberately: the log must not import db-p2p, so the dispute
|
|
76
|
+
* layer's richer `DisputeResolution` maps *onto* this proof rather than this proof importing it.
|
|
77
|
+
* A member treats the proof as a reversal certificate — `outcome === 'challenger-wins'` with a
|
|
78
|
+
* 2/3 super-majority of decisive votes agreeing with the challenger (each signature verifiable
|
|
79
|
+
* against its arbitrator's embedded key, each vote target-bound, drawn from the legitimately-selected
|
|
80
|
+
* {@link arbitratorSet}, and counted at most once per arbitrator).
|
|
81
|
+
*
|
|
82
|
+
* **Unforgeability.** Votes are bound to the reversed transaction (`targetHash`, #2), counted at most
|
|
83
|
+
* once per arbitrator (#3), and bound to the legitimately-selected arbitrator set (#1):
|
|
84
|
+
* {@link arbitratorSet} carries the K peer-ids the challenger selected, every counted vote must be a
|
|
85
|
+
* member of it, and {@link arbitratorSetSignature} — the challenger's Ed25519 signature (verified
|
|
86
|
+
* against {@link challengerPeerId}) over `(disputeId, target, arbitratorSet)` — binds the set to the
|
|
87
|
+
* originator so a third-party relay cannot swap in its own sybils. A verifying member additionally
|
|
88
|
+
* re-derives the eligible set from its own topology when it can (an injected recompute capability),
|
|
89
|
+
* closing even a fully-malicious challenger; when it cannot (late-joiner / churned DHT view) it accepts
|
|
90
|
+
* on the challenger-bound set + membership + dedup and *logs* the residual topology-anchoring gap rather
|
|
91
|
+
* than silently accepting — a gap closed in full by the cohort-topic membership-cert trust-anchor chain
|
|
92
|
+
* (`tickets/plan/cohort-topic-membership-cert-trust-anchoring.md`). Net: a compromised peer can withhold
|
|
93
|
+
* an invalidation but cannot forge one.
|
|
94
|
+
*/
|
|
95
|
+
export type DisputeResolutionProof = {
|
|
96
|
+
/** Identifies the dispute these votes resolved. */
|
|
97
|
+
readonly disputeId: string;
|
|
98
|
+
/** messageHash of the original (now-invalid) committed transaction. */
|
|
99
|
+
readonly messageHash: string;
|
|
100
|
+
/** Resolution outcome; only `challenger-wins` authorizes an invalidation. */
|
|
101
|
+
readonly outcome: 'challenger-wins' | 'majority-wins' | 'inconclusive';
|
|
102
|
+
/**
|
|
103
|
+
* Peer-id of the challenger (dissent coordinator) that selected the arbitrator set and produced
|
|
104
|
+
* {@link arbitratorSetSignature}; its embedded Ed25519 key verifies that signature.
|
|
105
|
+
*/
|
|
106
|
+
readonly challengerPeerId: string;
|
|
107
|
+
/**
|
|
108
|
+
* The legitimately-selected arbitrator set — the K peer-ids the challenger computed via
|
|
109
|
+
* `selectArbitrators` (the next K peers beyond the original cluster by XOR distance to the disputed
|
|
110
|
+
* block). Every counted vote's `arbitratorPeerId` must be a member; the set is bound to the originator
|
|
111
|
+
* by {@link arbitratorSetSignature} and, when feasible, re-derived from the verifying member's topology.
|
|
112
|
+
*/
|
|
113
|
+
readonly arbitratorSet: ReadonlyArray<string>;
|
|
114
|
+
/**
|
|
115
|
+
* The challenger's base64url Ed25519 signature (verified against {@link challengerPeerId}'s embedded
|
|
116
|
+
* key) over `utf8(`v3set:${disputeId}:${targetHash}:${setHash}`)` — binds `(disputeId, target,
|
|
117
|
+
* arbitratorSet)` to the originator so a relay cannot substitute its own cohort. Tampering with
|
|
118
|
+
* {@link arbitratorSet} (e.g. adding sybils) invalidates this signature.
|
|
119
|
+
*/
|
|
120
|
+
readonly arbitratorSetSignature: string;
|
|
121
|
+
/** Signed arbitrator votes. */
|
|
122
|
+
readonly votes: ReadonlyArray<ArbitrationVoteProof>;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/** Per-block compensating result an invalidation produced. */
|
|
126
|
+
export type RevertedBlock = {
|
|
127
|
+
/** Block whose tip was reverted. */
|
|
128
|
+
readonly blockId: BlockId;
|
|
129
|
+
/** Revision the block was at before this invalidation (the tip that was reverted). */
|
|
130
|
+
readonly fromRev: number;
|
|
131
|
+
/** Content hash of the new revision restoring the as-if-`T_inv`-absent content. */
|
|
132
|
+
readonly restoredContentHash: string;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** A compensating entry that reverses a previously-committed action proven invalid by dispute. */
|
|
136
|
+
export type InvalidationEntry = {
|
|
137
|
+
/** actionId of the committed {@link ActionEntry} being reversed. */
|
|
138
|
+
readonly invalidatedActionId: ActionId;
|
|
139
|
+
/** rev of the invalidated entry — pins which block revisions to roll back. */
|
|
140
|
+
readonly invalidatedRev: number;
|
|
141
|
+
/** Authoritative proof: a challenger-wins resolution carrying the signed arbitrator votes. */
|
|
142
|
+
readonly resolution: DisputeResolutionProof;
|
|
143
|
+
/** Per-block compensating result this entry produced (new monotonic revision restoring pre-`T_inv` content). */
|
|
144
|
+
readonly reverted: ReadonlyArray<RevertedBlock>;
|
|
145
|
+
/** When this invalidation is a cascade step, the root invalidation that triggered it (unused this ticket; see cascade ticket). */
|
|
146
|
+
readonly cascadeRoot?: ActionId;
|
|
23
147
|
};
|
|
24
148
|
|
|
25
149
|
/** A checkpoint entry restates the currently uncheckpointed actions */
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — cohort-side capability-filter evaluation (db-core, pure).
|
|
3
|
+
*
|
|
4
|
+
* Per `docs/matchmaking.md` §Capability filter: the filter is evaluated **locally at the cohort** and
|
|
5
|
+
* is **advisory only** — it biases which providers the cohort returns but is never admission. The
|
|
6
|
+
* seeker re-validates the returned set (`registrationSig`) and escalates if the filter matches too
|
|
7
|
+
* little (§Edge cases 4). A pathological filter that matches almost nothing is therefore acceptable.
|
|
8
|
+
*
|
|
9
|
+
* Semantics (`docs/matchmaking.md` §Capability filter / §Wire formats):
|
|
10
|
+
* - `must` — every tag must be present in the provider's `capabilities`.
|
|
11
|
+
* - `mustNot` — no tag may be present in the provider's `capabilities`.
|
|
12
|
+
* - `minBudget` — when set, the provider's `capacityBudget` must be `>= minBudget`.
|
|
13
|
+
*
|
|
14
|
+
* An absent filter matches every provider.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { CapabilityFilter } from "./wire.js";
|
|
18
|
+
|
|
19
|
+
/** The provider attributes a {@link CapabilityFilter} is evaluated against. */
|
|
20
|
+
export interface FilterableProvider {
|
|
21
|
+
readonly capabilities: readonly string[];
|
|
22
|
+
readonly capacityBudget: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** True iff `p` satisfies `f` (`must` ⊆ caps, `mustNot` ∩ caps = ∅, `capacityBudget >= minBudget`). */
|
|
26
|
+
export function matchesFilter(p: FilterableProvider, f: CapabilityFilter | undefined): boolean {
|
|
27
|
+
if (f === undefined) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
const caps = new Set(p.capabilities);
|
|
31
|
+
for (const tag of f.must) {
|
|
32
|
+
if (!caps.has(tag)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const tag of f.mustNot) {
|
|
37
|
+
if (caps.has(tag)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (f.minBudget !== undefined && p.capacityBudget < f.minBudget) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — configuration defaults.
|
|
3
|
+
*
|
|
4
|
+
* Transcribed from `docs/matchmaking.md` §Configuration. This module owns the matchmaking config
|
|
5
|
+
* surface: the **wire/TTL** constants (provider/seeker TTLs, the query limit, the seeker renew grace,
|
|
6
|
+
* the aggregate-count minimum tier) AND the seeker **hang-out tuning** rows (`patience_*`,
|
|
7
|
+
* `filter_accept_ratio_initial`, `contention_factor_cap`, `requery_interval_ms`, `mean_want_count`)
|
|
8
|
+
* consumed by the {@link import("./seeker-walk.js").decide} engine and the db-p2p seeker-walk client.
|
|
9
|
+
*
|
|
10
|
+
* The TTL/limit constants are wire-stable and do **not** depend on simulator findings; the hang-out
|
|
11
|
+
* rows DO (folded via `fold-simulator-findings-into-design-docs`) — they carry the simulator-validated
|
|
12
|
+
* defaults (`contention_factor_cap = 4.0`, `mean_want_count = 3`, …; see `docs/matchmaking.md`
|
|
13
|
+
* §Configuration "Defaults validated by simulator"). The `push_*` rows belong to the arrival-push
|
|
14
|
+
* path (a separate slice) and are intentionally not modeled here.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { NodeProfile } from "../cohort-topic/tiers.js";
|
|
18
|
+
|
|
19
|
+
/** Provider registration TTL on a Core node (ms). */
|
|
20
|
+
export const PROVIDER_TTL_CORE_MS = 90_000;
|
|
21
|
+
/** Provider registration TTL on an Edge node (ms). */
|
|
22
|
+
export const PROVIDER_TTL_EDGE_MS = 60_000;
|
|
23
|
+
/** Seeker registration TTL (ms) — short, since seekers normally don't wait long. */
|
|
24
|
+
export const SEEKER_TTL_MS = 10_000;
|
|
25
|
+
/** Documented seeker-TTL range (ms); `SEEKER_TTL_MS` sits inside it. */
|
|
26
|
+
export const SEEKER_TTL_MIN_MS = 5_000;
|
|
27
|
+
export const SEEKER_TTL_MAX_MS = 15_000;
|
|
28
|
+
/** Max entries returned in a single `QueryV1` reply. */
|
|
29
|
+
export const QUERY_LIMIT_MAX = 256;
|
|
30
|
+
/** Grace window a seeker may keep querying after its TTL expires (ms). */
|
|
31
|
+
export const SEEKER_RENEW_GRACE_MS = 5_000;
|
|
32
|
+
/** Root cohorts produce aggregate counts only when tree depth ≥ this. */
|
|
33
|
+
export const AGGREGATE_COUNT_MINIMUM_TIER = 1;
|
|
34
|
+
|
|
35
|
+
// --- Seeker hang-out tuning (simulator-folded; consumed by seeker-walk.ts + the walk client) ---
|
|
36
|
+
|
|
37
|
+
/** Fallback `patienceMs` when a caller does not specify it per-task (ms). */
|
|
38
|
+
export const PATIENCE_DEFAULT_MS = 10_000;
|
|
39
|
+
/** Fraction of remaining patience spent at one tier before considering escalation (1.0 = spend it all here). */
|
|
40
|
+
export const PATIENCE_PER_TIER_FRACTION = 1.0;
|
|
41
|
+
/** Starting estimate for `filterAcceptRatio`, refined per walk from observed query yields. */
|
|
42
|
+
export const FILTER_ACCEPT_RATIO_INITIAL = 1.0;
|
|
43
|
+
/** Upper bound on the contention multiplier in the hang-out decision (simulator-validated global scalar). */
|
|
44
|
+
export const CONTENTION_FACTOR_CAP = 4.0;
|
|
45
|
+
/** Mean `wantCount` assumed for competing seekers in the contention estimate (small constant; simulator value). */
|
|
46
|
+
export const MEAN_WANT_COUNT_DEFAULT = 3;
|
|
47
|
+
/** How often a hanging-out seeker re-issues `QueryV1` on the non-push (poll) path (ms). */
|
|
48
|
+
export const REQUERY_INTERVAL_MS = 1_000;
|
|
49
|
+
/** Window the seeker's primary batches fresh matchable arrivals before flushing one push (ms; arrival-push path). */
|
|
50
|
+
export const PUSH_COALESCE_MS = 250;
|
|
51
|
+
/** Sparse fallback `QueryV1` cadence for a push-aware hanging-out seeker (ms; arrival-push path). */
|
|
52
|
+
export const PUSH_SAFETY_POLL_MS = 5_000;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The seeker hang-out decision tuning (`docs/matchmaking.md` §Hang-out vs. continue / §Configuration).
|
|
56
|
+
* `meanWantCount` lives here because {@link import("./seeker-walk.js").SeekerDecisionInputs} carries it
|
|
57
|
+
* per-call (it may be learned), but the default is this constant.
|
|
58
|
+
*/
|
|
59
|
+
export interface HangOutConfig {
|
|
60
|
+
/** Clamp on the contention multiplier; protects against pathological `queriesPerMin / arrivalsPerMin`. */
|
|
61
|
+
readonly contentionFactorCap: number;
|
|
62
|
+
/** Hang-out poll cadence on the non-push path. */
|
|
63
|
+
readonly requeryIntervalMs: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The default hang-out decision config (simulator-validated). */
|
|
67
|
+
export const DEFAULT_HANG_OUT_CONFIG: HangOutConfig = {
|
|
68
|
+
contentionFactorCap: CONTENTION_FACTOR_CAP,
|
|
69
|
+
requeryIntervalMs: REQUERY_INTERVAL_MS,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/** The full matchmaking config, with the documented defaults. */
|
|
73
|
+
export interface MatchmakingConfig {
|
|
74
|
+
readonly providerTtlCoreMs: number;
|
|
75
|
+
readonly providerTtlEdgeMs: number;
|
|
76
|
+
readonly seekerTtlMs: number;
|
|
77
|
+
readonly queryLimitMax: number;
|
|
78
|
+
readonly seekerRenewGraceMs: number;
|
|
79
|
+
readonly aggregateCountMinimumTier: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The default matchmaking config (this ticket's slice). */
|
|
83
|
+
export const DEFAULT_MATCHMAKING_CONFIG: MatchmakingConfig = {
|
|
84
|
+
providerTtlCoreMs: PROVIDER_TTL_CORE_MS,
|
|
85
|
+
providerTtlEdgeMs: PROVIDER_TTL_EDGE_MS,
|
|
86
|
+
seekerTtlMs: SEEKER_TTL_MS,
|
|
87
|
+
queryLimitMax: QUERY_LIMIT_MAX,
|
|
88
|
+
seekerRenewGraceMs: SEEKER_RENEW_GRACE_MS,
|
|
89
|
+
aggregateCountMinimumTier: AGGREGATE_COUNT_MINIMUM_TIER,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Provider TTL for a node profile: Core nodes hold registrations for `PROVIDER_TTL_CORE_MS`, Edge
|
|
94
|
+
* nodes for the shorter `PROVIDER_TTL_EDGE_MS` (`docs/matchmaking.md` §Provider registration).
|
|
95
|
+
*/
|
|
96
|
+
export function providerTtlForProfile(profile: NodeProfile, config: MatchmakingConfig = DEFAULT_MATCHMAKING_CONFIG): number {
|
|
97
|
+
return profile.kind === "edge" ? config.providerTtlEdgeMs : config.providerTtlCoreMs;
|
|
98
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — the directory application of the cohort-topic substrate.
|
|
3
|
+
*
|
|
4
|
+
* See `docs/matchmaking.md`. The db-core layer owns the transport-agnostic pieces: wire codecs +
|
|
5
|
+
* seeker-side entry re-validation, the stable topic-anchor derivation, configuration, both
|
|
6
|
+
* registration roles' decision/state (provider attach/renew/self-throttle; seeker short-TTL
|
|
7
|
+
* registration), the cohort-side capability filter + pure query evaluation, and the seeker
|
|
8
|
+
* hang-out-vs-continue decision engine. The db-p2p layer wires these to the cohort-topic substrate
|
|
9
|
+
* (managers, the cohort query handler, the seeker walk client).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export * from "./config.js";
|
|
13
|
+
export * from "./topic-anchor.js";
|
|
14
|
+
export * from "./wire.js";
|
|
15
|
+
export * from "./provider.js";
|
|
16
|
+
export * from "./seeker.js";
|
|
17
|
+
export * from "./capability-filter.js";
|
|
18
|
+
export * from "./query-eval.js";
|
|
19
|
+
export * from "./seeker-walk.js";
|
|
20
|
+
export * from "./multi-cohort-seeker.js";
|
|
21
|
+
export * from "./voting-quorum.js";
|