@origintrail-official/dkg-agent 10.0.19 → 10.0.21
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/approved-private-replica.d.ts +54 -0
- package/dist/approved-private-replica.d.ts.map +1 -0
- package/dist/approved-private-replica.js +148 -0
- package/dist/approved-private-replica.js.map +1 -0
- package/dist/bounded-operation.d.ts +2 -0
- package/dist/bounded-operation.d.ts.map +1 -1
- package/dist/bounded-operation.js +5 -0
- package/dist/bounded-operation.js.map +1 -1
- package/dist/chain-finality-confirmations-v1.d.ts +7 -0
- package/dist/chain-finality-confirmations-v1.d.ts.map +1 -0
- package/dist/chain-finality-confirmations-v1.js +9 -0
- package/dist/chain-finality-confirmations-v1.js.map +1 -0
- package/dist/chain-reconciler.d.ts +23 -0
- package/dist/chain-reconciler.d.ts.map +1 -1
- package/dist/chain-reconciler.js +35 -0
- package/dist/chain-reconciler.js.map +1 -1
- package/dist/confirmed-graph-scoped-vm-resolver.d.ts +7 -1
- package/dist/confirmed-graph-scoped-vm-resolver.d.ts.map +1 -1
- package/dist/confirmed-graph-scoped-vm-resolver.js +5 -3
- package/dist/confirmed-graph-scoped-vm-resolver.js.map +1 -1
- package/dist/context-graph-authority-dependency.d.ts +11 -0
- package/dist/context-graph-authority-dependency.d.ts.map +1 -0
- package/dist/context-graph-authority-dependency.js +50 -0
- package/dist/context-graph-authority-dependency.js.map +1 -0
- package/dist/context-graph-binding-state.d.ts +6 -0
- package/dist/context-graph-binding-state.d.ts.map +1 -1
- package/dist/context-graph-binding-state.js +17 -10
- package/dist/context-graph-binding-state.js.map +1 -1
- package/dist/context-graph-claim-proof.d.ts +74 -0
- package/dist/context-graph-claim-proof.d.ts.map +1 -0
- package/dist/context-graph-claim-proof.js +137 -0
- package/dist/context-graph-claim-proof.js.map +1 -0
- package/dist/context-graph-member-proof.d.ts +33 -0
- package/dist/context-graph-member-proof.d.ts.map +1 -0
- package/dist/context-graph-member-proof.js +142 -0
- package/dist/context-graph-member-proof.js.map +1 -0
- package/dist/context-graph-membership-persist-scheduler.d.ts +7 -23
- package/dist/context-graph-membership-persist-scheduler.d.ts.map +1 -1
- package/dist/context-graph-membership-persist-scheduler.js +12 -88
- package/dist/context-graph-membership-persist-scheduler.js.map +1 -1
- package/dist/context-graph-meta-confirmation.d.ts +22 -2
- package/dist/context-graph-meta-confirmation.d.ts.map +1 -1
- package/dist/context-graph-meta-confirmation.js +54 -23
- package/dist/context-graph-meta-confirmation.js.map +1 -1
- package/dist/context-graph-meta-projection.d.ts +13 -2
- package/dist/context-graph-meta-projection.d.ts.map +1 -1
- package/dist/context-graph-meta-projection.js +61 -24
- package/dist/context-graph-meta-projection.js.map +1 -1
- package/dist/context-graph-metadata-relocation.d.ts +18 -30
- package/dist/context-graph-metadata-relocation.d.ts.map +1 -1
- package/dist/context-graph-metadata-relocation.js +32 -2
- package/dist/context-graph-metadata-relocation.js.map +1 -1
- package/dist/context-graph-private-meta-proof.d.ts +8 -9
- package/dist/context-graph-private-meta-proof.d.ts.map +1 -1
- package/dist/context-graph-private-meta-proof.js +25 -89
- package/dist/context-graph-private-meta-proof.js.map +1 -1
- package/dist/context-graph-public-meta-proof.d.ts +11 -1
- package/dist/context-graph-public-meta-proof.d.ts.map +1 -1
- package/dist/context-graph-public-meta-proof.js +23 -3
- package/dist/context-graph-public-meta-proof.js.map +1 -1
- package/dist/context-graph-read-authority.d.ts +30 -3
- package/dist/context-graph-read-authority.d.ts.map +1 -1
- package/dist/context-graph-read-authority.js +62 -18
- package/dist/context-graph-read-authority.js.map +1 -1
- package/dist/context-graph-storage-discovery.d.ts +14 -4
- package/dist/context-graph-storage-discovery.d.ts.map +1 -1
- package/dist/context-graph-storage-discovery.js +27 -7
- package/dist/context-graph-storage-discovery.js.map +1 -1
- package/dist/context-graph-subscription-authority-recovery.d.ts +7 -0
- package/dist/context-graph-subscription-authority-recovery.d.ts.map +1 -1
- package/dist/context-graph-subscription-authority-recovery.js +1 -0
- package/dist/context-graph-subscription-authority-recovery.js.map +1 -1
- package/dist/context-graph-subscription-persist-scheduler.d.ts +52 -0
- package/dist/context-graph-subscription-persist-scheduler.d.ts.map +1 -0
- package/dist/context-graph-subscription-persist-scheduler.js +78 -0
- package/dist/context-graph-subscription-persist-scheduler.js.map +1 -0
- package/dist/curator-dial-address.d.ts +16 -0
- package/dist/curator-dial-address.d.ts.map +1 -0
- package/dist/curator-dial-address.js +58 -0
- package/dist/curator-dial-address.js.map +1 -0
- package/dist/curator-meta-refresh.d.ts +18 -4
- package/dist/curator-meta-refresh.d.ts.map +1 -1
- package/dist/curator-meta-refresh.js +61 -58
- package/dist/curator-meta-refresh.js.map +1 -1
- package/dist/curator-peer-connection.d.ts +21 -0
- package/dist/curator-peer-connection.d.ts.map +1 -0
- package/dist/curator-peer-connection.js +41 -0
- package/dist/curator-peer-connection.js.map +1 -0
- package/dist/dkg-agent-agents-phonebook.d.ts +41 -0
- package/dist/dkg-agent-agents-phonebook.d.ts.map +1 -0
- package/dist/dkg-agent-agents-phonebook.js +155 -0
- package/dist/dkg-agent-agents-phonebook.js.map +1 -0
- package/dist/dkg-agent-base.d.ts +162 -24
- package/dist/dkg-agent-base.d.ts.map +1 -1
- package/dist/dkg-agent-base.js +175 -147
- package/dist/dkg-agent-base.js.map +1 -1
- package/dist/dkg-agent-cg-chain-observation.d.ts +6 -1
- package/dist/dkg-agent-cg-chain-observation.d.ts.map +1 -1
- package/dist/dkg-agent-cg-chain-observation.js +20 -5
- package/dist/dkg-agent-cg-chain-observation.js.map +1 -1
- package/dist/dkg-agent-cg-name-resolution.d.ts +38 -2
- package/dist/dkg-agent-cg-name-resolution.d.ts.map +1 -1
- package/dist/dkg-agent-cg-name-resolution.js +100 -8
- package/dist/dkg-agent-cg-name-resolution.js.map +1 -1
- package/dist/dkg-agent-cg-registry.d.ts +43 -3
- package/dist/dkg-agent-cg-registry.d.ts.map +1 -1
- package/dist/dkg-agent-cg-registry.js +267 -129
- package/dist/dkg-agent-cg-registry.js.map +1 -1
- package/dist/dkg-agent-cg-resolve.d.ts +6 -4
- package/dist/dkg-agent-cg-resolve.d.ts.map +1 -1
- package/dist/dkg-agent-cg-resolve.js +40 -18
- package/dist/dkg-agent-cg-resolve.js.map +1 -1
- package/dist/dkg-agent-constants.d.ts +10 -2
- package/dist/dkg-agent-constants.d.ts.map +1 -1
- package/dist/dkg-agent-constants.js +10 -2
- package/dist/dkg-agent-constants.js.map +1 -1
- package/dist/dkg-agent-context-graph.d.ts.map +1 -1
- package/dist/dkg-agent-context-graph.js +1 -5
- package/dist/dkg-agent-context-graph.js.map +1 -1
- package/dist/dkg-agent-crypto.d.ts +128 -21
- package/dist/dkg-agent-crypto.d.ts.map +1 -1
- package/dist/dkg-agent-crypto.js +824 -176
- package/dist/dkg-agent-crypto.js.map +1 -1
- package/dist/dkg-agent-diagnostics.d.ts.map +1 -1
- package/dist/dkg-agent-diagnostics.js +4 -3
- package/dist/dkg-agent-diagnostics.js.map +1 -1
- package/dist/dkg-agent-helpers.d.ts +2 -2
- package/dist/dkg-agent-helpers.d.ts.map +1 -1
- package/dist/dkg-agent-helpers.js +3 -3
- package/dist/dkg-agent-helpers.js.map +1 -1
- package/dist/dkg-agent-join.d.ts +12 -1
- package/dist/dkg-agent-join.d.ts.map +1 -1
- package/dist/dkg-agent-join.js +80 -92
- package/dist/dkg-agent-join.js.map +1 -1
- package/dist/dkg-agent-lifecycle.d.ts +129 -22
- package/dist/dkg-agent-lifecycle.d.ts.map +1 -1
- package/dist/dkg-agent-lifecycle.js +690 -211
- package/dist/dkg-agent-lifecycle.js.map +1 -1
- package/dist/dkg-agent-publish.d.ts +33 -40
- package/dist/dkg-agent-publish.d.ts.map +1 -1
- package/dist/dkg-agent-publish.js +194 -281
- package/dist/dkg-agent-publish.js.map +1 -1
- package/dist/dkg-agent-query.d.ts +7 -0
- package/dist/dkg-agent-query.d.ts.map +1 -1
- package/dist/dkg-agent-query.js +102 -86
- package/dist/dkg-agent-query.js.map +1 -1
- package/dist/dkg-agent-registered-private-empty-vm.d.ts +70 -0
- package/dist/dkg-agent-registered-private-empty-vm.d.ts.map +1 -0
- package/dist/dkg-agent-registered-private-empty-vm.js +133 -0
- package/dist/dkg-agent-registered-private-empty-vm.js.map +1 -0
- package/dist/dkg-agent-rfc64-catalog-auto-publish.d.ts +8 -3
- package/dist/dkg-agent-rfc64-catalog-auto-publish.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-catalog-auto-publish.js +45 -51
- package/dist/dkg-agent-rfc64-catalog-auto-publish.js.map +1 -1
- package/dist/dkg-agent-rfc64-catalog.d.ts +87 -80
- package/dist/dkg-agent-rfc64-catalog.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-catalog.js +726 -476
- package/dist/dkg-agent-rfc64-catalog.js.map +1 -1
- package/dist/dkg-agent-rfc64-meta-bootstrap.d.ts +6 -1
- package/dist/dkg-agent-rfc64-meta-bootstrap.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-meta-bootstrap.js +29 -13
- package/dist/dkg-agent-rfc64-meta-bootstrap.js.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.d.ts +8 -0
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.js +249 -40
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.js.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection.js +3 -2
- package/dist/dkg-agent-rfc64-swm-catalog-projection.js.map +1 -1
- package/dist/dkg-agent-swm-host.d.ts +217 -52
- package/dist/dkg-agent-swm-host.d.ts.map +1 -1
- package/dist/dkg-agent-swm-host.js +1305 -858
- package/dist/dkg-agent-swm-host.js.map +1 -1
- package/dist/dkg-agent-swm-state.d.ts +15 -0
- package/dist/dkg-agent-swm-state.d.ts.map +1 -1
- package/dist/dkg-agent-swm-state.js +43 -0
- package/dist/dkg-agent-swm-state.js.map +1 -1
- package/dist/dkg-agent-swm-substrate.d.ts +49 -8
- package/dist/dkg-agent-swm-substrate.d.ts.map +1 -1
- package/dist/dkg-agent-swm-substrate.js +219 -46
- package/dist/dkg-agent-swm-substrate.js.map +1 -1
- package/dist/dkg-agent-types.d.ts +86 -27
- package/dist/dkg-agent-types.d.ts.map +1 -1
- package/dist/dkg-agent-types.js.map +1 -1
- package/dist/dkg-agent-vm-promotion.d.ts +4 -0
- package/dist/dkg-agent-vm-promotion.d.ts.map +1 -1
- package/dist/dkg-agent-vm-promotion.js +40 -5
- package/dist/dkg-agent-vm-promotion.js.map +1 -1
- package/dist/dkg-agent-vm-reconcile-scheduling.d.ts +7 -0
- package/dist/dkg-agent-vm-reconcile-scheduling.d.ts.map +1 -1
- package/dist/dkg-agent-vm-reconcile-scheduling.js +18 -0
- package/dist/dkg-agent-vm-reconcile-scheduling.js.map +1 -1
- package/dist/dkg-agent.d.ts +31 -2
- package/dist/dkg-agent.d.ts.map +1 -1
- package/dist/dkg-agent.js +188 -72
- package/dist/dkg-agent.js.map +1 -1
- package/dist/exact-graph-content-verifier.d.ts.map +1 -1
- package/dist/exact-graph-content-verifier.js +3 -2
- package/dist/exact-graph-content-verifier.js.map +1 -1
- package/dist/finalization-handler.d.ts +26 -211
- package/dist/finalization-handler.d.ts.map +1 -1
- package/dist/finalization-handler.js +94 -1652
- package/dist/finalization-handler.js.map +1 -1
- package/dist/finalization-recovery-sqlite-displacement.d.ts +37 -0
- package/dist/finalization-recovery-sqlite-displacement.d.ts.map +1 -0
- package/dist/finalization-recovery-sqlite-displacement.js +102 -0
- package/dist/finalization-recovery-sqlite-displacement.js.map +1 -0
- package/dist/finalization-recovery-sqlite-policy.d.ts +20 -4
- package/dist/finalization-recovery-sqlite-policy.d.ts.map +1 -1
- package/dist/finalization-recovery-sqlite-policy.js +21 -5
- package/dist/finalization-recovery-sqlite-policy.js.map +1 -1
- package/dist/finalization-recovery-sqlite-rows.d.ts +53 -0
- package/dist/finalization-recovery-sqlite-rows.d.ts.map +1 -0
- package/dist/finalization-recovery-sqlite-rows.js +77 -0
- package/dist/finalization-recovery-sqlite-rows.js.map +1 -0
- package/dist/finalization-recovery-sqlite-store.d.ts +10 -4
- package/dist/finalization-recovery-sqlite-store.d.ts.map +1 -1
- package/dist/finalization-recovery-sqlite-store.js +49 -50
- package/dist/finalization-recovery-sqlite-store.js.map +1 -1
- package/dist/finalization-recovery-store.d.ts +18 -0
- package/dist/finalization-recovery-store.d.ts.map +1 -1
- package/dist/finalization-recovery-store.js +24 -0
- package/dist/finalization-recovery-store.js.map +1 -1
- package/dist/finalization-recovery-worker.js +1 -1
- package/dist/finalization-recovery-worker.js.map +1 -1
- package/dist/finalization-recovery.d.ts +2 -3
- package/dist/finalization-recovery.d.ts.map +1 -1
- package/dist/finalization-recovery.js +12 -9
- package/dist/finalization-recovery.js.map +1 -1
- package/dist/finalized-authority-cold-resolution.d.ts +6 -1
- package/dist/finalized-authority-cold-resolution.d.ts.map +1 -1
- package/dist/finalized-authority-cold-resolution.js +22 -3
- package/dist/finalized-authority-cold-resolution.js.map +1 -1
- package/dist/gossip-publish-handler.d.ts.map +1 -1
- package/dist/gossip-publish-handler.js +4 -2
- package/dist/gossip-publish-handler.js.map +1 -1
- package/dist/gossip-session.d.ts +29 -0
- package/dist/gossip-session.d.ts.map +1 -0
- package/dist/gossip-session.js +48 -0
- package/dist/gossip-session.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/context-graph-authority/approved-member-acceptance.d.ts +61 -0
- package/dist/internal/context-graph-authority/approved-member-acceptance.d.ts.map +1 -0
- package/dist/internal/context-graph-authority/approved-member-acceptance.js +75 -0
- package/dist/internal/context-graph-authority/approved-member-acceptance.js.map +1 -0
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.d.ts +5 -5
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.d.ts.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.js +59 -49
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.js.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-authority.d.ts +1 -0
- package/dist/internal/context-graph-authority/context-graph-authority.d.ts.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-authority.js +25 -0
- package/dist/internal/context-graph-authority/context-graph-authority.js.map +1 -1
- package/dist/internal/context-graph-authority/finalized-target-projection.d.ts +17 -0
- package/dist/internal/context-graph-authority/finalized-target-projection.d.ts.map +1 -0
- package/dist/internal/context-graph-authority/finalized-target-projection.js +36 -0
- package/dist/internal/context-graph-authority/finalized-target-projection.js.map +1 -0
- package/dist/internal/context-graph-authority/swm-transport-authority.d.ts +84 -0
- package/dist/internal/context-graph-authority/swm-transport-authority.d.ts.map +1 -0
- package/dist/internal/context-graph-authority/swm-transport-authority.js +175 -0
- package/dist/internal/context-graph-authority/swm-transport-authority.js.map +1 -0
- package/dist/internal/context-graph-binding-abort.d.ts +3 -0
- package/dist/internal/context-graph-binding-abort.d.ts.map +1 -0
- package/dist/internal/context-graph-binding-abort.js +32 -0
- package/dist/internal/context-graph-binding-abort.js.map +1 -0
- package/dist/internal/context-graph-cache-invalidating-store.d.ts +3 -0
- package/dist/internal/context-graph-cache-invalidating-store.d.ts.map +1 -0
- package/dist/internal/context-graph-cache-invalidating-store.js +167 -0
- package/dist/internal/context-graph-cache-invalidating-store.js.map +1 -0
- package/dist/internal/context-graph-meta-record-copy.d.ts +3 -0
- package/dist/internal/context-graph-meta-record-copy.d.ts.map +1 -0
- package/dist/internal/context-graph-meta-record-copy.js +21 -0
- package/dist/internal/context-graph-meta-record-copy.js.map +1 -0
- package/dist/internal/gossip/host-mode-handler.d.ts +11 -0
- package/dist/internal/gossip/host-mode-handler.d.ts.map +1 -0
- package/dist/internal/gossip/host-mode-handler.js +41 -0
- package/dist/internal/gossip/host-mode-handler.js.map +1 -0
- package/dist/internal/join-encryption-key-bundle.d.ts +10 -0
- package/dist/internal/join-encryption-key-bundle.d.ts.map +1 -0
- package/dist/internal/join-encryption-key-bundle.js +72 -0
- package/dist/internal/join-encryption-key-bundle.js.map +1 -0
- package/dist/internal/knowledge-asset-vm-publish-request.d.ts +31 -0
- package/dist/internal/knowledge-asset-vm-publish-request.d.ts.map +1 -0
- package/dist/internal/knowledge-asset-vm-publish-request.js +91 -0
- package/dist/internal/knowledge-asset-vm-publish-request.js.map +1 -0
- package/dist/internal/lifecycle-sync-policy.d.ts +5 -0
- package/dist/internal/lifecycle-sync-policy.d.ts.map +1 -0
- package/dist/internal/lifecycle-sync-policy.js +12 -0
- package/dist/internal/lifecycle-sync-policy.js.map +1 -0
- package/dist/internal/local-private-member.d.ts +14 -0
- package/dist/internal/local-private-member.d.ts.map +1 -0
- package/dist/internal/local-private-member.js +21 -0
- package/dist/internal/local-private-member.js.map +1 -0
- package/dist/internal/promote/assertion-promote-precommit.d.ts +41 -1
- package/dist/internal/promote/assertion-promote-precommit.d.ts.map +1 -1
- package/dist/internal/promote/assertion-promote-precommit.js +79 -22
- package/dist/internal/promote/assertion-promote-precommit.js.map +1 -1
- package/dist/internal/storage-ack-owned-request.d.ts +16 -0
- package/dist/internal/storage-ack-owned-request.d.ts.map +1 -0
- package/dist/internal/storage-ack-owned-request.js +16 -0
- package/dist/internal/storage-ack-owned-request.js.map +1 -0
- package/dist/internal/vm-reconcile-local-admission-wait.d.ts +96 -0
- package/dist/internal/vm-reconcile-local-admission-wait.d.ts.map +1 -0
- package/dist/internal/vm-reconcile-local-admission-wait.js +226 -0
- package/dist/internal/vm-reconcile-local-admission-wait.js.map +1 -0
- package/dist/internal/vm-reconcile-read-authority.d.ts +27 -0
- package/dist/internal/vm-reconcile-read-authority.d.ts.map +1 -0
- package/dist/internal/vm-reconcile-read-authority.js +33 -0
- package/dist/internal/vm-reconcile-read-authority.js.map +1 -0
- package/dist/internal/vm-reconcile-sweep-admission.d.ts +2 -0
- package/dist/internal/vm-reconcile-sweep-admission.d.ts.map +1 -1
- package/dist/internal/vm-reconcile-sweep.d.ts +16 -4
- package/dist/internal/vm-reconcile-sweep.d.ts.map +1 -1
- package/dist/internal/vm-reconcile-sweep.js +91 -50
- package/dist/internal/vm-reconcile-sweep.js.map +1 -1
- package/dist/internal/workspace-projected-delegatees.d.ts +3 -0
- package/dist/internal/workspace-projected-delegatees.d.ts.map +1 -0
- package/dist/internal/workspace-projected-delegatees.js +34 -0
- package/dist/internal/workspace-projected-delegatees.js.map +1 -0
- package/dist/join-approval-restart-projection.d.ts +14 -0
- package/dist/join-approval-restart-projection.d.ts.map +1 -0
- package/dist/join-approval-restart-projection.js +32 -0
- package/dist/join-approval-restart-projection.js.map +1 -0
- package/dist/keyed-persist-scheduler.d.ts +72 -0
- package/dist/keyed-persist-scheduler.d.ts.map +1 -0
- package/dist/keyed-persist-scheduler.js +140 -0
- package/dist/keyed-persist-scheduler.js.map +1 -0
- package/dist/map-with-concurrency.d.ts +7 -0
- package/dist/map-with-concurrency.d.ts.map +1 -1
- package/dist/map-with-concurrency.js +36 -0
- package/dist/map-with-concurrency.js.map +1 -1
- package/dist/p2p/network-admission-coordinator.d.ts +15 -0
- package/dist/p2p/network-admission-coordinator.d.ts.map +1 -1
- package/dist/p2p/network-admission-coordinator.js +20 -2
- package/dist/p2p/network-admission-coordinator.js.map +1 -1
- package/dist/p2p/peer-connect.d.ts +10 -1
- package/dist/p2p/peer-connect.d.ts.map +1 -1
- package/dist/p2p/peer-connect.js +11 -2
- package/dist/p2p/peer-connect.js.map +1 -1
- package/dist/p2p/peer-selection.d.ts +8 -0
- package/dist/p2p/peer-selection.d.ts.map +1 -1
- package/dist/p2p/peer-selection.js +21 -12
- package/dist/p2p/peer-selection.js.map +1 -1
- package/dist/p2p/protocol-readiness.d.ts +3 -3
- package/dist/p2p/protocol-readiness.d.ts.map +1 -1
- package/dist/p2p/protocol-readiness.js +4 -3
- package/dist/p2p/protocol-readiness.js.map +1 -1
- package/dist/prepare-unscoped-context-graph-read-checks.d.ts.map +1 -1
- package/dist/prepare-unscoped-context-graph-read-checks.js +12 -0
- package/dist/prepare-unscoped-context-graph-read-checks.js.map +1 -1
- package/dist/registered-context-graph-authority.d.ts +19 -0
- package/dist/registered-context-graph-authority.d.ts.map +1 -1
- package/dist/registered-private-empty-vm-attempt-v1.d.ts +34 -0
- package/dist/registered-private-empty-vm-attempt-v1.d.ts.map +1 -0
- package/dist/registered-private-empty-vm-attempt-v1.js +120 -0
- package/dist/registered-private-empty-vm-attempt-v1.js.map +1 -0
- package/dist/reserved-ka-id-allocation.d.ts +12 -0
- package/dist/reserved-ka-id-allocation.d.ts.map +1 -0
- package/dist/reserved-ka-id-allocation.js +25 -0
- package/dist/reserved-ka-id-allocation.js.map +1 -0
- package/dist/rfc64/applied-catalog-authority-transition-v1.d.ts.map +1 -1
- package/dist/rfc64/applied-catalog-authority-transition-v1.js +15 -17
- package/dist/rfc64/applied-catalog-authority-transition-v1.js.map +1 -1
- package/dist/rfc64/authority-rpc-circuit-breaker-v1.d.ts +5 -3
- package/dist/rfc64/authority-rpc-circuit-breaker-v1.d.ts.map +1 -1
- package/dist/rfc64/authority-rpc-circuit-breaker-v1.js +9 -0
- package/dist/rfc64/authority-rpc-circuit-breaker-v1.js.map +1 -1
- package/dist/rfc64/catalog-completion-evidence-v1.d.ts +38 -0
- package/dist/rfc64/catalog-completion-evidence-v1.d.ts.map +1 -0
- package/dist/rfc64/catalog-completion-evidence-v1.js +49 -0
- package/dist/rfc64/catalog-completion-evidence-v1.js.map +1 -0
- package/dist/rfc64/catalog-operational-applied-heads-v1.d.ts +12 -13
- package/dist/rfc64/catalog-operational-applied-heads-v1.d.ts.map +1 -1
- package/dist/rfc64/catalog-operational-applied-heads-v1.js +17 -52
- package/dist/rfc64/catalog-operational-applied-heads-v1.js.map +1 -1
- package/dist/rfc64/catalog-operational-reads-v1.d.ts +13 -0
- package/dist/rfc64/catalog-operational-reads-v1.d.ts.map +1 -0
- package/dist/rfc64/catalog-operational-reads-v1.js +56 -0
- package/dist/rfc64/catalog-operational-reads-v1.js.map +1 -0
- package/dist/rfc64/catalog-operational-targets-v1.d.ts +55 -0
- package/dist/rfc64/catalog-operational-targets-v1.d.ts.map +1 -0
- package/dist/rfc64/catalog-operational-targets-v1.js +379 -0
- package/dist/rfc64/catalog-operational-targets-v1.js.map +1 -0
- package/dist/rfc64/catalog-repair-diagnostics-v1.d.ts +28 -0
- package/dist/rfc64/catalog-repair-diagnostics-v1.d.ts.map +1 -0
- package/dist/rfc64/catalog-repair-diagnostics-v1.js +93 -0
- package/dist/rfc64/catalog-repair-diagnostics-v1.js.map +1 -0
- package/dist/rfc64/catalog-repair-retry-v1.d.ts +13 -0
- package/dist/rfc64/catalog-repair-retry-v1.d.ts.map +1 -0
- package/dist/rfc64/catalog-repair-retry-v1.js +39 -0
- package/dist/rfc64/catalog-repair-retry-v1.js.map +1 -0
- package/dist/rfc64/catalog-replay-recovery-runtime-v1.d.ts +52 -0
- package/dist/rfc64/catalog-replay-recovery-runtime-v1.d.ts.map +1 -1
- package/dist/rfc64/catalog-replay-recovery-runtime-v1.js +188 -32
- package/dist/rfc64/catalog-replay-recovery-runtime-v1.js.map +1 -1
- package/dist/rfc64/catalog-replay-snapshot-runtime-v1.d.ts +2 -8
- package/dist/rfc64/catalog-replay-snapshot-runtime-v1.d.ts.map +1 -1
- package/dist/rfc64/catalog-replay-snapshot-runtime-v1.js +10 -37
- package/dist/rfc64/catalog-replay-snapshot-runtime-v1.js.map +1 -1
- package/dist/rfc64/catalog-rollout-authority-v1.d.ts +13 -0
- package/dist/rfc64/catalog-rollout-authority-v1.d.ts.map +1 -1
- package/dist/rfc64/catalog-rollout-authority-v1.js +11 -0
- package/dist/rfc64/catalog-rollout-authority-v1.js.map +1 -1
- package/dist/rfc64/catalog-row-authorship.d.ts +12 -0
- package/dist/rfc64/catalog-row-authorship.d.ts.map +1 -1
- package/dist/rfc64/catalog-row-authorship.js +110 -57
- package/dist/rfc64/catalog-row-authorship.js.map +1 -1
- package/dist/rfc64/inventory-v1/candidate.d.ts +31 -10
- package/dist/rfc64/inventory-v1/candidate.d.ts.map +1 -1
- package/dist/rfc64/inventory-v1/candidate.js +51 -16
- package/dist/rfc64/inventory-v1/candidate.js.map +1 -1
- package/dist/rfc64/inventory-v1/index.d.ts +1 -1
- package/dist/rfc64/inventory-v1/index.d.ts.map +1 -1
- package/dist/rfc64/inventory-v1/index.js +1 -1
- package/dist/rfc64/inventory-v1/index.js.map +1 -1
- package/dist/rfc64/inventory-v1/open.d.ts.map +1 -1
- package/dist/rfc64/inventory-v1/open.js +7 -4
- package/dist/rfc64/inventory-v1/open.js.map +1 -1
- package/dist/rfc64/inventory-v1/swm-author-inventory-persistence.d.ts +3 -1
- package/dist/rfc64/inventory-v1/swm-author-inventory-persistence.d.ts.map +1 -1
- package/dist/rfc64/inventory-v1/swm-author-inventory-persistence.js +15 -0
- package/dist/rfc64/inventory-v1/swm-author-inventory-persistence.js.map +1 -1
- package/dist/rfc64/legacy-swm-boundary-codec-v1.d.ts +25 -0
- package/dist/rfc64/legacy-swm-boundary-codec-v1.d.ts.map +1 -0
- package/dist/rfc64/legacy-swm-boundary-codec-v1.js +127 -0
- package/dist/rfc64/legacy-swm-boundary-codec-v1.js.map +1 -0
- package/dist/rfc64/legacy-swm-boundary-v1.d.ts +12 -0
- package/dist/rfc64/legacy-swm-boundary-v1.d.ts.map +1 -1
- package/dist/rfc64/legacy-swm-boundary-v1.js +83 -144
- package/dist/rfc64/legacy-swm-boundary-v1.js.map +1 -1
- package/dist/rfc64/private-catalog-subscription-readiness-v1.d.ts +33 -0
- package/dist/rfc64/private-catalog-subscription-readiness-v1.d.ts.map +1 -0
- package/dist/rfc64/private-catalog-subscription-readiness-v1.js +97 -0
- package/dist/rfc64/private-catalog-subscription-readiness-v1.js.map +1 -0
- package/dist/rfc64/private-read-roster-v1.d.ts +14 -0
- package/dist/rfc64/private-read-roster-v1.d.ts.map +1 -0
- package/dist/rfc64/private-read-roster-v1.js +57 -0
- package/dist/rfc64/private-read-roster-v1.js.map +1 -0
- package/dist/rfc64/public-catalog-native-receiver-v1.d.ts.map +1 -1
- package/dist/rfc64/public-catalog-native-receiver-v1.js +26 -21
- package/dist/rfc64/public-catalog-native-receiver-v1.js.map +1 -1
- package/dist/rfc64/public-catalog-native-reconciler-v1.d.ts +17 -11
- package/dist/rfc64/public-catalog-native-reconciler-v1.d.ts.map +1 -1
- package/dist/rfc64/public-catalog-native-reconciler-v1.js +10 -8
- package/dist/rfc64/public-catalog-native-reconciler-v1.js.map +1 -1
- package/dist/rfc64/public-catalog-receiver-v1.d.ts +9 -0
- package/dist/rfc64/public-catalog-receiver-v1.d.ts.map +1 -1
- package/dist/rfc64/public-catalog-receiver-v1.js +11 -2
- package/dist/rfc64/public-catalog-receiver-v1.js.map +1 -1
- package/dist/rfc64/public-catalog-service-v1.d.ts.map +1 -1
- package/dist/rfc64/public-catalog-service-v1.js +21 -22
- package/dist/rfc64/public-catalog-service-v1.js.map +1 -1
- package/dist/rfc64/public-catalog-successor-producer-v1.d.ts.map +1 -1
- package/dist/rfc64/public-catalog-successor-producer-v1.js +5 -4
- package/dist/rfc64/public-catalog-successor-producer-v1.js.map +1 -1
- package/dist/rfc64/registered-private-empty-vm-proof-v1.d.ts +20 -0
- package/dist/rfc64/registered-private-empty-vm-proof-v1.d.ts.map +1 -0
- package/dist/rfc64/registered-private-empty-vm-proof-v1.js +26 -0
- package/dist/rfc64/registered-private-empty-vm-proof-v1.js.map +1 -0
- package/dist/rfc64/swm-catalog-durable-asset-resolver-v1.d.ts.map +1 -1
- package/dist/rfc64/swm-catalog-durable-asset-resolver-v1.js +60 -53
- package/dist/rfc64/swm-catalog-durable-asset-resolver-v1.js.map +1 -1
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.d.ts +2 -1
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.d.ts.map +1 -1
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.js +44 -4
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.js.map +1 -1
- package/dist/rfc64/swm-inventory-shadow-runtime-v1.d.ts +3 -1
- package/dist/rfc64/swm-inventory-shadow-runtime-v1.d.ts.map +1 -1
- package/dist/rfc64/swm-inventory-shadow-runtime-v1.js +34 -0
- package/dist/rfc64/swm-inventory-shadow-runtime-v1.js.map +1 -1
- package/dist/sync/auth/pipe-request-tail.d.ts +5 -1
- package/dist/sync/auth/pipe-request-tail.d.ts.map +1 -1
- package/dist/sync/auth/pipe-request-tail.js +13 -3
- package/dist/sync/auth/pipe-request-tail.js.map +1 -1
- package/dist/sync/auth/request-build.d.ts +3 -0
- package/dist/sync/auth/request-build.d.ts.map +1 -1
- package/dist/sync/auth/request-build.js +11 -2
- package/dist/sync/auth/request-build.js.map +1 -1
- package/dist/sync/backpressure.d.ts +27 -16
- package/dist/sync/backpressure.d.ts.map +1 -1
- package/dist/sync/backpressure.js +66 -40
- package/dist/sync/backpressure.js.map +1 -1
- package/dist/sync/catchup-policy.d.ts +2 -0
- package/dist/sync/catchup-policy.d.ts.map +1 -1
- package/dist/sync/catchup-policy.js +2 -0
- package/dist/sync/catchup-policy.js.map +1 -1
- package/dist/sync/exact-asset-fetch.d.ts +22 -0
- package/dist/sync/exact-asset-fetch.d.ts.map +1 -1
- package/dist/sync/exact-asset-fetch.js +30 -3
- package/dist/sync/exact-asset-fetch.js.map +1 -1
- package/dist/sync/exact-assets.d.ts +7 -5
- package/dist/sync/exact-assets.d.ts.map +1 -1
- package/dist/sync/exact-assets.js +13 -8
- package/dist/sync/exact-assets.js.map +1 -1
- package/dist/sync/exact-batch-observation.d.ts +3 -0
- package/dist/sync/exact-batch-observation.d.ts.map +1 -0
- package/dist/sync/exact-batch-observation.js +13 -0
- package/dist/sync/exact-batch-observation.js.map +1 -0
- package/dist/sync/exact-batch-stream-capability.d.ts +24 -0
- package/dist/sync/exact-batch-stream-capability.d.ts.map +1 -0
- package/dist/sync/exact-batch-stream-capability.js +88 -0
- package/dist/sync/exact-batch-stream-capability.js.map +1 -0
- package/dist/sync/exact-batch-stream-contract.d.ts +78 -0
- package/dist/sync/exact-batch-stream-contract.d.ts.map +1 -0
- package/dist/sync/exact-batch-stream-contract.js +206 -0
- package/dist/sync/exact-batch-stream-contract.js.map +1 -0
- package/dist/sync/on-connect/sync-on-connect.d.ts +1 -1
- package/dist/sync/on-connect/sync-on-connect.d.ts.map +1 -1
- package/dist/sync/on-connect/sync-on-connect.js +3 -3
- package/dist/sync/on-connect/sync-on-connect.js.map +1 -1
- package/dist/sync/on-demand-agents-phonebook.d.ts +162 -0
- package/dist/sync/on-demand-agents-phonebook.d.ts.map +1 -0
- package/dist/sync/on-demand-agents-phonebook.js +571 -0
- package/dist/sync/on-demand-agents-phonebook.js.map +1 -0
- package/dist/sync/peer-connection.d.ts.map +1 -1
- package/dist/sync/peer-connection.js +11 -2
- package/dist/sync/peer-connection.js.map +1 -1
- package/dist/sync/priority-admission-queue.d.ts +17 -0
- package/dist/sync/priority-admission-queue.d.ts.map +1 -1
- package/dist/sync/priority-admission-queue.js +58 -37
- package/dist/sync/priority-admission-queue.js.map +1 -1
- package/dist/sync/requester/admission-boundary.d.ts +12 -0
- package/dist/sync/requester/admission-boundary.d.ts.map +1 -0
- package/dist/sync/requester/admission-boundary.js +22 -0
- package/dist/sync/requester/admission-boundary.js.map +1 -0
- package/dist/sync/requester/durable-sync.d.ts +2 -1
- package/dist/sync/requester/durable-sync.d.ts.map +1 -1
- package/dist/sync/requester/durable-sync.js +3 -188
- package/dist/sync/requester/durable-sync.js.map +1 -1
- package/dist/sync/requester/exact-batch-stream-driver.d.ts +83 -0
- package/dist/sync/requester/exact-batch-stream-driver.d.ts.map +1 -0
- package/dist/sync/requester/exact-batch-stream-driver.js +299 -0
- package/dist/sync/requester/exact-batch-stream-driver.js.map +1 -0
- package/dist/sync/requester/exact-batch-stream.d.ts +72 -0
- package/dist/sync/requester/exact-batch-stream.d.ts.map +1 -0
- package/dist/sync/requester/exact-batch-stream.js +267 -0
- package/dist/sync/requester/exact-batch-stream.js.map +1 -0
- package/dist/sync/requester/exact-recovery-transport.d.ts +19 -0
- package/dist/sync/requester/exact-recovery-transport.d.ts.map +1 -0
- package/dist/sync/requester/exact-recovery-transport.js +3 -0
- package/dist/sync/requester/exact-recovery-transport.js.map +1 -0
- package/dist/sync/requester/finalized-swm-twin-reconciliation.js +12 -3
- package/dist/sync/requester/finalized-swm-twin-reconciliation.js.map +1 -1
- package/dist/sync/requester/graph-scoped-materialization.d.ts.map +1 -1
- package/dist/sync/requester/graph-scoped-materialization.js +61 -27
- package/dist/sync/requester/graph-scoped-materialization.js.map +1 -1
- package/dist/sync/requester/page-fetch.d.ts +7 -0
- package/dist/sync/requester/page-fetch.d.ts.map +1 -1
- package/dist/sync/requester/page-fetch.js +103 -49
- package/dist/sync/requester/page-fetch.js.map +1 -1
- package/dist/sync/requester/shared-memory-sync.d.ts +10 -5
- package/dist/sync/requester/shared-memory-sync.d.ts.map +1 -1
- package/dist/sync/requester/shared-memory-sync.js +149 -150
- package/dist/sync/requester/shared-memory-sync.js.map +1 -1
- package/dist/sync/requester/swm-materialization-memo.d.ts +12 -0
- package/dist/sync/requester/swm-materialization-memo.d.ts.map +1 -0
- package/dist/sync/requester/swm-materialization-memo.js +54 -0
- package/dist/sync/requester/swm-materialization-memo.js.map +1 -0
- package/dist/sync/requester/swm-recovery.d.ts +3 -29
- package/dist/sync/requester/swm-recovery.d.ts.map +1 -1
- package/dist/sync/requester/swm-recovery.js +11 -10
- package/dist/sync/requester/swm-recovery.js.map +1 -1
- package/dist/sync/requester/swm-snapshot-materializer.d.ts.map +1 -1
- package/dist/sync/requester/swm-snapshot-materializer.js +18 -0
- package/dist/sync/requester/swm-snapshot-materializer.js.map +1 -1
- package/dist/sync/requester/swm-target-executor.d.ts +6 -0
- package/dist/sync/requester/swm-target-executor.d.ts.map +1 -1
- package/dist/sync/requester/swm-target-executor.js +24 -3
- package/dist/sync/requester/swm-target-executor.js.map +1 -1
- package/dist/sync/requester/verified-asset-preparation.d.ts +9 -0
- package/dist/sync/requester/verified-asset-preparation.d.ts.map +1 -0
- package/dist/sync/requester/verified-asset-preparation.js +190 -0
- package/dist/sync/requester/verified-asset-preparation.js.map +1 -0
- package/dist/sync/responder/asset-metadata.d.ts +18 -0
- package/dist/sync/responder/asset-metadata.d.ts.map +1 -0
- package/dist/sync/responder/asset-metadata.js +27 -0
- package/dist/sync/responder/asset-metadata.js.map +1 -0
- package/dist/sync/responder/durable-data-request-policy.d.ts +2 -16
- package/dist/sync/responder/durable-data-request-policy.d.ts.map +1 -1
- package/dist/sync/responder/durable-data-request-policy.js +1 -31
- package/dist/sync/responder/durable-data-request-policy.js.map +1 -1
- package/dist/sync/responder/exact-asset-export-cache.d.ts +89 -0
- package/dist/sync/responder/exact-asset-export-cache.d.ts.map +1 -0
- package/dist/sync/responder/exact-asset-export-cache.js +550 -0
- package/dist/sync/responder/exact-asset-export-cache.js.map +1 -0
- package/dist/sync/responder/exact-batch-stream.d.ts +47 -0
- package/dist/sync/responder/exact-batch-stream.d.ts.map +1 -0
- package/dist/sync/responder/exact-batch-stream.js +151 -0
- package/dist/sync/responder/exact-batch-stream.js.map +1 -0
- package/dist/sync/responder/exact-data-session.d.ts +67 -0
- package/dist/sync/responder/exact-data-session.d.ts.map +1 -0
- package/dist/sync/responder/exact-data-session.js +130 -0
- package/dist/sync/responder/exact-data-session.js.map +1 -0
- package/dist/sync/responder/exact-graph-cursor-filter.d.ts +9 -0
- package/dist/sync/responder/exact-graph-cursor-filter.d.ts.map +1 -0
- package/dist/sync/responder/exact-graph-cursor-filter.js +101 -0
- package/dist/sync/responder/exact-graph-cursor-filter.js.map +1 -0
- package/dist/sync/responder/exact-graph-reader.d.ts +95 -0
- package/dist/sync/responder/exact-graph-reader.d.ts.map +1 -0
- package/dist/sync/responder/exact-graph-reader.js +623 -0
- package/dist/sync/responder/exact-graph-reader.js.map +1 -0
- package/dist/sync/responder/exact-page-reader.d.ts +37 -0
- package/dist/sync/responder/exact-page-reader.d.ts.map +1 -0
- package/dist/sync/responder/exact-page-reader.js +130 -0
- package/dist/sync/responder/exact-page-reader.js.map +1 -0
- package/dist/sync/responder/graph-plan.d.ts +19 -85
- package/dist/sync/responder/graph-plan.d.ts.map +1 -1
- package/dist/sync/responder/graph-plan.js +51 -988
- package/dist/sync/responder/graph-plan.js.map +1 -1
- package/dist/sync/responder/page-framing-policy.d.ts +31 -0
- package/dist/sync/responder/page-framing-policy.d.ts.map +1 -0
- package/dist/sync/responder/page-framing-policy.js +41 -0
- package/dist/sync/responder/page-framing-policy.js.map +1 -0
- package/dist/sync/responder/responder-row-page.d.ts +85 -0
- package/dist/sync/responder/responder-row-page.d.ts.map +1 -0
- package/dist/sync/responder/responder-row-page.js +181 -0
- package/dist/sync/responder/responder-row-page.js.map +1 -0
- package/dist/sync/responder/row-serialization.d.ts +34 -0
- package/dist/sync/responder/row-serialization.d.ts.map +1 -0
- package/dist/sync/responder/row-serialization.js +69 -0
- package/dist/sync/responder/row-serialization.js.map +1 -0
- package/dist/sync/responder/session-plan-memo.d.ts +20 -0
- package/dist/sync/responder/session-plan-memo.d.ts.map +1 -0
- package/dist/sync/responder/session-plan-memo.js +135 -0
- package/dist/sync/responder/session-plan-memo.js.map +1 -0
- package/dist/sync/responder/sync-handler.d.ts +26 -1
- package/dist/sync/responder/sync-handler.d.ts.map +1 -1
- package/dist/sync/responder/sync-handler.js +107 -58
- package/dist/sync/responder/sync-handler.js.map +1 -1
- package/dist/sync/shared-memory-completion.d.ts +30 -0
- package/dist/sync/shared-memory-completion.d.ts.map +1 -1
- package/dist/sync/shared-memory-completion.js +13 -0
- package/dist/sync/shared-memory-completion.js.map +1 -1
- package/dist/sync/system-context-graph-policy.d.ts +10 -0
- package/dist/sync/system-context-graph-policy.d.ts.map +1 -1
- package/dist/sync/system-context-graph-policy.js +11 -0
- package/dist/sync/system-context-graph-policy.js.map +1 -1
- package/dist/sync/wire-compression.d.ts +47 -0
- package/dist/sync/wire-compression.d.ts.map +1 -0
- package/dist/sync/wire-compression.js +111 -0
- package/dist/sync/wire-compression.js.map +1 -0
- package/dist/unscoped-query-consistency.d.ts +12 -0
- package/dist/unscoped-query-consistency.d.ts.map +1 -1
- package/dist/unscoped-query-consistency.js +17 -1
- package/dist/unscoped-query-consistency.js.map +1 -1
- package/dist/vm-promotion-audit.d.ts +2 -2
- package/dist/vm-promotion-audit.d.ts.map +1 -1
- package/dist/vm-promotion-audit.js +26 -9
- package/dist/vm-promotion-audit.js.map +1 -1
- package/dist/vm-publish-snapshot-preflight.d.ts +13 -0
- package/dist/vm-publish-snapshot-preflight.d.ts.map +1 -0
- package/dist/vm-publish-snapshot-preflight.js +94 -0
- package/dist/vm-publish-snapshot-preflight.js.map +1 -0
- package/dist/vm-reconcile-dispatcher.d.ts +42 -1
- package/dist/vm-reconcile-dispatcher.d.ts.map +1 -1
- package/dist/vm-reconcile-dispatcher.js +103 -4
- package/dist/vm-reconcile-dispatcher.js.map +1 -1
- package/dist/vm-reconcile-peer-topology.d.ts +7 -9
- package/dist/vm-reconcile-peer-topology.d.ts.map +1 -1
- package/dist/vm-reconcile-peer-topology.js +1 -37
- package/dist/vm-reconcile-peer-topology.js.map +1 -1
- package/dist/vm-recovery-candidate-order.d.ts +16 -0
- package/dist/vm-recovery-candidate-order.d.ts.map +1 -0
- package/dist/vm-recovery-candidate-order.js +24 -0
- package/dist/vm-recovery-candidate-order.js.map +1 -0
- package/dist/vm-recovery-core-transport-preference.d.ts +69 -0
- package/dist/vm-recovery-core-transport-preference.d.ts.map +1 -0
- package/dist/vm-recovery-core-transport-preference.js +131 -0
- package/dist/vm-recovery-core-transport-preference.js.map +1 -0
- package/dist/vm-recovery-experiment-policy.d.ts +24 -0
- package/dist/vm-recovery-experiment-policy.d.ts.map +1 -0
- package/dist/vm-recovery-experiment-policy.js +18 -0
- package/dist/vm-recovery-experiment-policy.js.map +1 -0
- package/dist/vm-recovery-footprint.d.ts +54 -0
- package/dist/vm-recovery-footprint.d.ts.map +1 -1
- package/dist/vm-recovery-footprint.js +88 -24
- package/dist/vm-recovery-footprint.js.map +1 -1
- package/dist/vm-recovery-microbatch.d.ts +2 -0
- package/dist/vm-recovery-microbatch.d.ts.map +1 -1
- package/dist/vm-recovery-microbatch.js +7 -3
- package/dist/vm-recovery-microbatch.js.map +1 -1
- package/dist/vm-recovery-pass-authority.d.ts +84 -0
- package/dist/vm-recovery-pass-authority.d.ts.map +1 -0
- package/dist/vm-recovery-pass-authority.js +126 -0
- package/dist/vm-recovery-pass-authority.js.map +1 -0
- package/dist/vm-recovery-phase-timing.d.ts +75 -0
- package/dist/vm-recovery-phase-timing.d.ts.map +1 -0
- package/dist/vm-recovery-phase-timing.js +236 -0
- package/dist/vm-recovery-phase-timing.js.map +1 -0
- package/dist/vm-recovery-preparation.d.ts +143 -0
- package/dist/vm-recovery-preparation.d.ts.map +1 -0
- package/dist/vm-recovery-preparation.js +433 -0
- package/dist/vm-recovery-preparation.js.map +1 -0
- package/dist/vm-recovery-provider-policy.d.ts +13 -1
- package/dist/vm-recovery-provider-policy.d.ts.map +1 -1
- package/dist/vm-recovery-provider-policy.js +37 -5
- package/dist/vm-recovery-provider-policy.js.map +1 -1
- package/dist/vm-recovery-stream-profile.d.ts +15 -0
- package/dist/vm-recovery-stream-profile.d.ts.map +1 -0
- package/dist/vm-recovery-stream-profile.js +53 -0
- package/dist/vm-recovery-stream-profile.js.map +1 -0
- package/dist/vm-recovery-stream-setback-policy.d.ts +54 -0
- package/dist/vm-recovery-stream-setback-policy.d.ts.map +1 -0
- package/dist/vm-recovery-stream-setback-policy.js +85 -0
- package/dist/vm-recovery-stream-setback-policy.js.map +1 -0
- package/dist/vm-recovery-timing-observer.d.ts +27 -0
- package/dist/vm-recovery-timing-observer.d.ts.map +1 -0
- package/dist/vm-recovery-timing-observer.js +49 -0
- package/dist/vm-recovery-timing-observer.js.map +1 -0
- package/dist/vm-recovery-transport-budget-policy.d.ts +32 -0
- package/dist/vm-recovery-transport-budget-policy.d.ts.map +1 -0
- package/dist/vm-recovery-transport-budget-policy.js +55 -0
- package/dist/vm-recovery-transport-budget-policy.js.map +1 -0
- package/dist/vm-recovery-transport-plan.d.ts +83 -0
- package/dist/vm-recovery-transport-plan.d.ts.map +1 -0
- package/dist/vm-recovery-transport-plan.js +117 -0
- package/dist/vm-recovery-transport-plan.js.map +1 -0
- package/dist/vm-refresh.d.ts +138 -0
- package/dist/vm-refresh.d.ts.map +1 -0
- package/dist/vm-refresh.js +201 -0
- package/dist/vm-refresh.js.map +1 -0
- package/package.json +19 -9
- package/dist/finalization-annotations.d.ts +0 -5
- package/dist/finalization-annotations.d.ts.map +0 -1
- package/dist/finalization-annotations.js +0 -6
- package/dist/finalization-annotations.js.map +0 -1
- package/dist/swm-ka-bound.d.ts +0 -21
- package/dist/swm-ka-bound.d.ts.map +0 -1
- package/dist/swm-ka-bound.js +0 -36
- package/dist/swm-ka-bound.js.map +0 -1
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { syncReconcilerEnabled, syncOnConnectEnabled, durableSyncEnabled } from './internal/lifecycle-sync-policy.js';
|
|
2
|
+
import { emptySwmRecoveryResult } from './sync/shared-memory-completion.js';
|
|
3
|
+
import { DurableSyncAdmissionBoundary } from './sync/requester/admission-boundary.js';
|
|
1
4
|
import { createRandomSamplingEligibilityResolver } from './random-sampling-eligibility.js';
|
|
2
5
|
import { RandomSamplingRuntime } from './random-sampling-runtime.js';
|
|
3
6
|
import { startAuthorityIndexSnapshotRuntime } from './authority-index-snapshot-runtime.js';
|
|
@@ -12,10 +15,11 @@ import { startAuthorityIndexSnapshotRuntime } from './authority-index-snapshot-r
|
|
|
12
15
|
import { traverseBoundedCuratorRoster, curatorRosterResolution, } from './bounded-curator-roster-traversal.js';
|
|
13
16
|
import { setTimeout as waitForPeerEventTurn } from 'node:timers/promises';
|
|
14
17
|
import { PeerSyncSession } from './sync/peer-sync-session.js';
|
|
18
|
+
import { captureExactBatchStreamRefusalScope } from './sync/exact-batch-stream-capability.js';
|
|
15
19
|
import { createStorageACKRegistrationPlan } from './p2p/storage-ack-registrar.js';
|
|
16
20
|
import { syncOpenedPeerConnection } from './sync/peer-connection.js';
|
|
17
21
|
import { isLegacySyncGraphCandidateV1 } from './sync/legacy-sync-graph-candidate.js';
|
|
18
|
-
import { ProtocolRouter, GossipSubManager, DKGEvent, LibP2PNetwork, PeerResolver, StubNetworkStateRegistry, PROTOCOL_ACCESS, PROTOCOL_PUBLISH, PROTOCOL_SYNC, PROTOCOL_SYNC_POOLED, PROTOCOL_SYNC_CHANGELOG, PROTOCOL_QUERY_REMOTE, PROTOCOL_GET_CIPHERTEXT_CHUNK, PROTOCOL_VERIFY_PROPOSAL, PROTOCOL_JOIN_REQUEST, PROTOCOL_NETWORK_IDENTITY, PROTOCOL_SWM_SENDER_KEY, PROTOCOL_SWM_UPDATE, PROTOCOL_SWM_SHARE_ACK, PROTOCOL_SWM_HOST_CATCHUP, PROTOCOL_MESSAGE, contextGraphDataGraphUri, contextGraphMetaGraphUri, contextGraphWorkspaceMetaGraphUri, contextGraphMetaUri, deriveCuratorDidFromCgId, SYSTEM_CONTEXT_GRAPHS, DKG_ONTOLOGY, GRAPH_KA_CONTENT_SCOPE_VERSION, validateSubGraphName, createOperationContext, isSafeIri, InMemoryMessageIdempotencyStore, InMemoryProtocolOutboxStore, assertBoundedProtocolOutboxStore, tripleContentV10, withRetry, } from '@origintrail-official/dkg-core';
|
|
22
|
+
import { ProtocolRouter, GossipSubManager, DKGEvent, registerExperimentalExactBatchResponder, LibP2PNetwork, PeerResolver, StubNetworkStateRegistry, PROTOCOL_ACCESS, PROTOCOL_PUBLISH, PROTOCOL_SYNC, PROTOCOL_SYNC_POOLED, PROTOCOL_SYNC_CHANGELOG, PROTOCOL_QUERY_REMOTE, PROTOCOL_GET_CIPHERTEXT_CHUNK, PROTOCOL_VERIFY_PROPOSAL, PROTOCOL_JOIN_REQUEST, PROTOCOL_NETWORK_IDENTITY, advertisesSyncProtocol, PROTOCOL_SWM_SENDER_KEY, PROTOCOL_SWM_UPDATE, PROTOCOL_SWM_SHARE_ACK, PROTOCOL_SWM_HOST_CATCHUP, PROTOCOL_MESSAGE, contextGraphDataGraphUri, contextGraphMetaGraphUri, contextGraphWorkspaceMetaGraphUri, contextGraphMetaUri, deriveCuratorDidFromCgId, SYSTEM_CONTEXT_GRAPHS, DKG_ONTOLOGY, GRAPH_KA_CONTENT_SCOPE_VERSION, validateSubGraphName, createOperationContext, isSafeIri, QuietRetryableHandlerError, InMemoryMessageIdempotencyStore, InMemoryProtocolOutboxStore, assertBoundedProtocolOutboxStore, tripleContentV10, withRetry, } from '@origintrail-official/dkg-core';
|
|
19
23
|
import { GraphManager, asChangelogReader } from '@origintrail-official/dkg-storage';
|
|
20
24
|
import { readChangelogDeltaPage } from './sync/responder/graph-plan.js';
|
|
21
25
|
import { decodeChangelogRequest, encodeChangelogResponse } from './sync/changelog/wire.js';
|
|
@@ -28,9 +32,11 @@ import { PublishHandler, ChainEventPoller, AccessHandler, PublishJournal, Verify
|
|
|
28
32
|
import { ethers } from 'ethers';
|
|
29
33
|
import { QueryHandler, } from '@origintrail-official/dkg-query';
|
|
30
34
|
import { repairCreatorPublicMetaProjections } from './context-graph-public-meta-repair.js';
|
|
35
|
+
import { METADATA_RELOCATION_STARTUP_BUDGET_MS } from './context-graph-metadata-relocation.js';
|
|
31
36
|
import { startRandomSamplingExactRepair, } from './sync/recovery/random-sampling-exact-repair.js';
|
|
32
37
|
import { reconcileConfiguredContextGraphMetadataV1, } from './configured-context-graph-metadata-reconciliation.js';
|
|
33
|
-
import { confirmContextGraphMetadataV1 } from './context-graph-meta-confirmation.js';
|
|
38
|
+
import { confirmContextGraphMetadataV1, } from './context-graph-meta-confirmation.js';
|
|
39
|
+
import { resolveApprovedMemberAcceptanceDecision, } from './internal/context-graph-authority/approved-member-acceptance.js';
|
|
34
40
|
import { MessageHandler } from './messaging.js';
|
|
35
41
|
import { ed25519ToX25519Private } from './encryption.js';
|
|
36
42
|
import { SyncVerifyWorker, } from './sync-verify-worker.js';
|
|
@@ -52,6 +58,7 @@ import { deleteSyncPageCheckpoint, fetchSyncPages, SyncPageSizeProfileCache, } f
|
|
|
52
58
|
import { composeSyncWorkAdmission, createSyncFetchSharingIdentity, } from './sync/work-admission.js';
|
|
53
59
|
import { createChallengePinnedExactAssetSelection, createUalOnlyExactAssetSelection, exactAssetUalsForSelection, exactAssetFilterKey, exactSyncPhaseAccumulationLimits, requireExactAssetSelection, } from './sync/exact-assets.js';
|
|
54
60
|
import { runOversizeSweep } from './sync/oversize-sweep.js';
|
|
61
|
+
import { EXACT_SYNC_GZIP_ENCODING, resolveExactSyncGzipProfile } from './sync/wire-compression.js';
|
|
55
62
|
import { MemorySyncCheckpointStore, } from './sync/checkpoint/state.js';
|
|
56
63
|
import { DurableRecoveryRunner, } from './sync/durable-recovery-runner.js';
|
|
57
64
|
import { createDurableSyncBudget, createDurableSyncFetchTimeoutMs, DURABLE_SYNC_SETTLEMENT_HEADROOM_MS, EXACT_RECOVERY_DURABLE_TRANSFER_TIMEOUT_MS, normalizeDurableSyncTimeoutMs, } from './sync/requester/durable-sync-budget.js';
|
|
@@ -61,25 +68,28 @@ import { mergeExactAssetResponderCapability, mergeExactDurableFetchDisposition,
|
|
|
61
68
|
import { resolveSyncAgentsMeta, shouldWithholdAgentsDurableMeta } from './sync/agents-meta-policy.js';
|
|
62
69
|
import { createSelectedSwmMetaRetentionBudget, } from './sync/selected-swm-meta-budget.js';
|
|
63
70
|
import { sharedMemoryOwnershipKeyFromGraph, } from './sync/requester/shared-memory-sync.js';
|
|
64
|
-
import { emptySharedMemorySyncResult
|
|
71
|
+
import { emptySharedMemorySyncResult, mergeSamePeerSharedMemoryDiagnostics, mergeFleetSharedMemoryDiagnostics, recordSharedMemoryPhaseFailure, } from './sync/shared-memory-diagnostics.js';
|
|
65
72
|
import { createSelectedSwmMetaFetcher, } from './sync/selected-swm-meta-fetcher.js';
|
|
66
73
|
import { runOrderedContextGraphSyncs, } from './sync/requester/ordered-sync.js';
|
|
67
74
|
import { registerSyncHandler, resolveSyncResponderSnapshotPolicy, } from './sync/responder/sync-handler.js';
|
|
75
|
+
import { createExactBatchResponderBinding } from './sync/responder/exact-batch-stream.js';
|
|
76
|
+
import { exactBatchTransportOptions } from './sync/requester/exact-batch-stream.js';
|
|
77
|
+
import { runExactBatchStreamDriver } from './sync/requester/exact-batch-stream-driver.js';
|
|
68
78
|
import { runSelectedSharedMemoryRetry, runRegistrySyncOnConnect, SyncOnConnectPostSyncError, } from './sync/on-connect/sync-on-connect.js';
|
|
69
79
|
import { captureSyncOnConnectAttempt, } from './sync/on-connect/attempt-accounting.js';
|
|
70
80
|
import { ReconciledSyncOnConnectPeerJobRunner } from './sync/on-connect/peer-job-runner.js';
|
|
71
81
|
import { formatPrivateRecoverySkip, planPrivateRecoverySource, } from './sync/private-recovery-source-planner.js';
|
|
72
82
|
import { mapWithConcurrency } from './map-with-concurrency.js';
|
|
73
83
|
import { CATCHUP_MAX_CONCURRENT_PEER_SYNCS } from './sync/catchup-concurrency.js';
|
|
74
|
-
import { FOREGROUND_CATCHUP_SYNC_PRIORITY, catchupAdmissionSource, runCatchupPlaneWithPolicy, runCatchupPlanesWithPolicy, } from './sync/catchup-policy.js';
|
|
84
|
+
import { FOREGROUND_CATCHUP_SYNC_PRIORITY, VM_RECOVERY_SYNC_PRIORITY, catchupAdmissionSource, runCatchupPlaneWithPolicy, runCatchupPlanesWithPolicy, } from './sync/catchup-policy.js';
|
|
75
85
|
import { SwmCatchupPassTracker, catchupPassNowMs, resolveSwmCatchupPassConfig, runSwmCatchupContinuations, } from './sync/catchup-pass-policy.js';
|
|
76
86
|
import { runSelectedSwmContinuations, } from './sync/selected-swm-continuation.js';
|
|
77
87
|
import { projectRfc64SelectedSwmGraphSyncStatus, } from './sync/selected-swm-graph-sync-status.js';
|
|
78
88
|
import { applySelectedSwmFreshnessResolution, } from './sync/shared-memory-freshness.js';
|
|
79
89
|
import { classifyDurableProgress, createDurableSyncAccumulator, createFailedPeerDurableSyncResult, createIncompleteDurableSyncResult, durableSyncAccumulatorHasPeerTransportFailure, durableSyncAccumulatorHasTerminalBoundary, durableSyncAccumulatorFromResult, finalizeDurableSyncCompletion, markDurableTerminalBoundary, mergeDurableSyncAccumulatorInto, mergeDurableSyncResultIntoAccumulator, recordDurableSyncDiagnostics, } from './sync/durable-progress.js';
|
|
80
|
-
import { getSyncBackpressureSnapshot, getSyncBackpressureBusyError,
|
|
90
|
+
import { getSyncBackpressureSnapshot, getSyncBackpressureBusyError, resolveExactBatchStreamEnabled, resolveSyncGlobalBackpressure, syncAdmissionWouldBeRefused, withGlobalSyncBackpressure, } from './sync/backpressure.js';
|
|
81
91
|
import { contextGraphPriority, countSyncPriorityClasses, normalizeSyncAdmissionSource, orderContextGraphIdsByPriority, syncPriorityClass, } from './sync/policy.js';
|
|
82
|
-
import { automaticDurableSyncContextGraphs } from './sync/system-context-graph-policy.js';
|
|
92
|
+
import { automaticDurableSyncContextGraphs, systemContextGraphSyncOptionsOf, } from './sync/system-context-graph-policy.js';
|
|
83
93
|
import { activeSyncAdmissionSource, monotonicNowMs, recordSyncAttempt, recordSyncAttemptRequestBytes, recordSyncAttemptResponseBytes, recordSyncOperationDuration, recordSyncOperationRejected, recordSyncSingleFlightJoin, syncAttemptAttributes, syncOperationRejectionReason, withSyncAdmissionSource, } from './sync/attempt-telemetry.js';
|
|
84
94
|
// rc.9 PR-10: JoinApprovalRetryQueue removed — substrate outbox
|
|
85
95
|
// (durable, SQLite-backed) replaces it. We keep a minimal local
|
|
@@ -96,6 +106,66 @@ const DEFAULT_MAX_REHYDRATED_SUBSCRIPTIONS = 64;
|
|
|
96
106
|
const REHYDRATE_THROTTLE_BATCH = 8;
|
|
97
107
|
/** Retry interval for a persisted-subscription activation that is waiting for a slot. */
|
|
98
108
|
const REHYDRATION_ROLLING_RETRY_MS = 30_000;
|
|
109
|
+
/**
|
|
110
|
+
* How long startup rehydration waits on persisted rows' read authority before
|
|
111
|
+
* leaving the rest to background authority recovery (#2815). Override via
|
|
112
|
+
* `DKGAgentConfig.contextGraphSubscriptionRehydrationAuthorityBudgetMs` (0
|
|
113
|
+
* removes the budget).
|
|
114
|
+
*/
|
|
115
|
+
const DEFAULT_REHYDRATION_STARTUP_AUTHORITY_BUDGET_MS = 10_000;
|
|
116
|
+
/** Longest delay a Node timer honours; a longer one fires after 1 ms. */
|
|
117
|
+
const MAX_REHYDRATION_AUTHORITY_BUDGET_MS = 2_147_483_647;
|
|
118
|
+
/** Stands in for an authority decision the startup budget stopped waiting for. */
|
|
119
|
+
const REHYDRATION_AUTHORITY_DEFERRED = Symbol('rehydration-authority-deferred');
|
|
120
|
+
/**
|
|
121
|
+
* Delays between attempts of a restarted join approval's metadata recovery
|
|
122
|
+
* after a transient failure; the last one repeats while the row stays
|
|
123
|
+
* restricted. One attempt is a single curator metadata fetch.
|
|
124
|
+
*/
|
|
125
|
+
const JOIN_APPROVAL_METADATA_RECOVERY_RETRY_MS = Object.freeze([15_000, 30_000, 60_000, 120_000, 300_000]);
|
|
126
|
+
/**
|
|
127
|
+
* Wait `ms` unless the node stops first; resolves whether the wait completed.
|
|
128
|
+
* The listener is removed either way, so nothing stays attached to the
|
|
129
|
+
* node-lifetime signal.
|
|
130
|
+
*/
|
|
131
|
+
function waitUnlessStopped(ms, stopSignal) {
|
|
132
|
+
return new Promise((resolve) => {
|
|
133
|
+
if (stopSignal?.aborted === true) {
|
|
134
|
+
resolve(false);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const onStop = () => {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
resolve(false);
|
|
140
|
+
};
|
|
141
|
+
const timer = setTimeout(() => {
|
|
142
|
+
stopSignal?.removeEventListener('abort', onStop);
|
|
143
|
+
resolve(true);
|
|
144
|
+
}, ms);
|
|
145
|
+
timer.unref?.();
|
|
146
|
+
stopSignal?.addEventListener('abort', onStop, { once: true });
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function startRehydrationAuthorityBudget(budgetMs) {
|
|
150
|
+
if (budgetMs === 0) {
|
|
151
|
+
return { spent: () => false, race: (decision) => decision, dispose: () => { } };
|
|
152
|
+
}
|
|
153
|
+
let spent = false;
|
|
154
|
+
let expire = () => { };
|
|
155
|
+
const expired = new Promise((resolve) => {
|
|
156
|
+
expire = () => resolve(REHYDRATION_AUTHORITY_DEFERRED);
|
|
157
|
+
});
|
|
158
|
+
const timer = setTimeout(() => {
|
|
159
|
+
spent = true;
|
|
160
|
+
expire();
|
|
161
|
+
}, budgetMs);
|
|
162
|
+
timer.unref?.();
|
|
163
|
+
return {
|
|
164
|
+
spent: () => spent,
|
|
165
|
+
race: (decision) => Promise.race([decision, expired]),
|
|
166
|
+
dispose: () => clearTimeout(timer),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
99
169
|
function rehydratedSubscriptionReachedSafeState(subscription) {
|
|
100
170
|
return subscription.synced === true
|
|
101
171
|
&& subscription.metaSynced !== false
|
|
@@ -116,6 +186,7 @@ import { stripLiteral, } from './dkg-agent-utils.js';
|
|
|
116
186
|
import { SYNC_BYTE_BUDGET_MAX_ROWS, SYNC_PAGE_SIZE, SYNC_REQUEST_PAGE_SIZE, SYNC_PAGE_RETRY_ATTEMPTS, SYNC_TOTAL_TIMEOUT_MS, SYNC_MIN_GRAPH_BUDGET_MS, SYNC_PAGE_TIMEOUT_MS, SYNC_ROUTER_ATTEMPTS, SYNC_PROTOCOL_CHECK_ATTEMPTS, SYNC_PROTOCOL_CHECK_DELAY_MS, SYNC_ACCESS_DENIED_MARKER, DEBUG_SYNC_PROGRESS, DEFAULT_SWM_TTL_MS, SWM_CLEANUP_INTERVAL_MS, SYNC_DENIED_RESPONSE, GOSSIP_DIAL_COOLDOWN_MS, GOSSIP_DIAL_TIMEOUT_MS, CATCHUP_ON_CONNECT_COOLDOWN_MS, SYNC_RECONNECT_FLAP_GRACE_MS, MESSAGE_OUTBOX_TICK_MS, AGENT_PROFILE_HEARTBEAT_MS, AGENT_PROFILE_STALE_THRESHOLD_MS, WARM_CORE_CONNECTIONS_ENABLED, WARM_CORE_RECONCILE_INTERVAL_MS, WARM_CORE_MAX, WARM_CORE_KEEPALIVE_TAG, WARM_CORE_DIAL_TIMEOUT_MS, BOOT_CHAIN_IDENTITY_TIMEOUT_MS, } from './dkg-agent-constants.js';
|
|
117
187
|
import { chainAuthorityReadBudgetsOf } from './chain-authority-read-budgets.js';
|
|
118
188
|
import { peekFinalizedAuthorityColdResolution } from './finalized-authority-cold-resolution.js';
|
|
189
|
+
import { AGENTS_PHONEBOOK_PRIME_MAX_DIALS, peekOnDemandAgentsPhonebook, } from './sync/on-demand-agents-phonebook.js';
|
|
119
190
|
import { raceWithBootTimeout, isTransientBootChainError } from './dkg-agent-boot.js';
|
|
120
191
|
import { normalizeContextGraphSubscriptionTransition, projectContextGraphSubscriptionPersistence, } from './context-graph-subscription-policy.js';
|
|
121
192
|
import { partitionSupersededContextGraphNamePlaceholders } from './dkg-agent-cg-name-resolution.js';
|
|
@@ -126,7 +197,9 @@ import { normalizeAgentDid, inferAdapterPublisherAddress, } from './dkg-agent-he
|
|
|
126
197
|
import { DKGAgentBase } from './dkg-agent-base.js';
|
|
127
198
|
import { VmReconcileShutdownTimeoutError } from './vm-reconcile-service.js';
|
|
128
199
|
import { ContextGraphMembershipPersistShutdownTimeoutError } from './context-graph-membership-persist-scheduler.js';
|
|
200
|
+
import { ContextGraphSubscriptionPersistShutdownTimeoutError } from './context-graph-subscription-persist-scheduler.js';
|
|
129
201
|
import { createLocalContextGraphOriginMembershipRecord, } from './local-context-graph-provenance.js';
|
|
202
|
+
import { contextGraphReadAuthorityDependencyOf, unavailableContextGraphReadAuthorityDecision, } from './context-graph-read-authority.js';
|
|
130
203
|
import { deterministicStartupJitterMs, scheduleAfterStartupJitter } from './startup-jitter.js';
|
|
131
204
|
import { projectContextGraphDormancy, } from './context-graph-subscription-dormancy.js';
|
|
132
205
|
import { activatePersistedContextGraphSubscription as activatePersistedContextGraphSubscriptionTransaction, recoverDeferredContextGraphSubscriptionAuthorities, } from './context-graph-subscription-authority-recovery.js';
|
|
@@ -135,34 +208,11 @@ import { isRfc64PrivateRecoveryOwnerV1, resolveRfc64PrivateRecoveryContextGraphI
|
|
|
135
208
|
import { CONTEXT_GRAPH_AUTHORITY_RPC_SITES as CG_AUTH_RPC_SITES, withRpcUsageSite, } from '@origintrail-official/dkg-chain';
|
|
136
209
|
import { rfc64ExecutionPlanAllowsLegacySyncV1, resolveRfc64RuntimeCatalogBootstrapConfigV1, } from './rfc64/public-catalog-activation-config-v1.js';
|
|
137
210
|
import { reconcileRfc64CatalogAuthorityPlanV1 } from './rfc64/catalog-rollout-authority-reconciliation-v1.js';
|
|
138
|
-
import { initializeRfc64LegacySwmBoundaryV1, prepareRfc64LateLegacySwmBoundaryV1, } from './rfc64/legacy-swm-boundary-v1.js';
|
|
211
|
+
import { initializeRfc64LegacySwmBoundaryV1, prepareRfc64LateLegacySwmBoundaryV1, retireRfc64LegacySwmAfterFinalizedVmV1, } from './rfc64/legacy-swm-boundary-v1.js';
|
|
212
|
+
import { projectPersistedJoinApprovals, } from './join-approval-restart-projection.js';
|
|
213
|
+
import { verifiedCuratorDialAddress } from './curator-dial-address.js';
|
|
139
214
|
const DEFAULT_HOST_MODE_RECONCILE_JITTER_RATIO = 0.15;
|
|
140
215
|
const RFC64_SELECTED_SWM_ADMISSION_PRIORITY = 2_000;
|
|
141
|
-
function projectPersistedJoinApprovals(persistedMembershipRows, persistedContextGraphIds, localAgentAddresses) {
|
|
142
|
-
const newestApprovalByContextGraph = new Map();
|
|
143
|
-
for (const membership of persistedMembershipRows) {
|
|
144
|
-
const principalId = membership.principalId.toLowerCase();
|
|
145
|
-
if (membership.principalType !== 'agent' ||
|
|
146
|
-
membership.status !== 'active' ||
|
|
147
|
-
membership.source !== 'join-approved' ||
|
|
148
|
-
!persistedContextGraphIds.has(membership.contextGraphId) ||
|
|
149
|
-
!localAgentAddresses.has(principalId)) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
const existing = newestApprovalByContextGraph.get(membership.contextGraphId);
|
|
153
|
-
if (!existing || membership.updatedAt > existing.updatedAt) {
|
|
154
|
-
newestApprovalByContextGraph.set(membership.contextGraphId, {
|
|
155
|
-
principalId,
|
|
156
|
-
updatedAt: membership.updatedAt,
|
|
157
|
-
curatorPeerId: typeof membership.metadata?.['curatorPeerId'] === 'string' &&
|
|
158
|
-
membership.metadata['curatorPeerId'].trim()
|
|
159
|
-
? membership.metadata['curatorPeerId'].trim()
|
|
160
|
-
: undefined,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return newestApprovalByContextGraph;
|
|
165
|
-
}
|
|
166
216
|
function resolveAgentSyncGlobalBackpressure(config) {
|
|
167
217
|
// `trackSyncContextGraph()` mutates this list when an Edge explicitly
|
|
168
218
|
// subscribes or starts a foreground catch-up. Those operator-selected graphs
|
|
@@ -363,6 +413,8 @@ function syncPageFetchCoalescingKey(params) {
|
|
|
363
413
|
params.assetUals === undefined ? null : exactAssetFilterKey(params.assetUals),
|
|
364
414
|
params.returnAcceptedPrefixOnRetryableTransportFailure === true,
|
|
365
415
|
params.requesterScope ?? null,
|
|
416
|
+
params.responseEncoding ?? null,
|
|
417
|
+
params.maxAcceptedBytes ?? null,
|
|
366
418
|
params.maxAcceptedQuads ?? null,
|
|
367
419
|
params.maxAcceptedHeapBytesEstimate ?? null,
|
|
368
420
|
]);
|
|
@@ -450,11 +502,14 @@ function contextGraphCatchupSingleFlightKey(params) {
|
|
|
450
502
|
function durableSyncSingleFlightKey(params) {
|
|
451
503
|
if (params.hasPhaseCallback
|
|
452
504
|
|| params.hasAtomicCommitCallback
|
|
505
|
+
|| params.hasWorkStartedCallback
|
|
453
506
|
|| params.hasAccessDeniedCallback
|
|
454
507
|
|| params.hasSinceBatchIdResolver
|
|
455
508
|
|| params.hasSignal
|
|
456
509
|
|| params.hasCurrentFence
|
|
457
|
-
|| params.hasChallengePinnedSelection
|
|
510
|
+
|| params.hasChallengePinnedSelection
|
|
511
|
+
|| params.hasForcedFreshExactSession
|
|
512
|
+
|| params.hasRegisteredPublicEvidence) {
|
|
458
513
|
return null;
|
|
459
514
|
}
|
|
460
515
|
return syncSingleFlightKey('durable-sync', {
|
|
@@ -466,6 +521,7 @@ function durableSyncSingleFlightKey(params) {
|
|
|
466
521
|
syncAgentsMeta: params.syncAgentsMeta,
|
|
467
522
|
exactAssetUals: params.exactAssetUals ?? null,
|
|
468
523
|
settlementSliceTimeoutMs: params.settlementSliceTimeoutMs ?? null,
|
|
524
|
+
exactRecoveryTransportMode: params.exactRecoveryTransportMode ?? 'stream-preferred',
|
|
469
525
|
priority: params.priority ?? null,
|
|
470
526
|
});
|
|
471
527
|
}
|
|
@@ -766,42 +822,16 @@ async function authenticateDurableGraphScopedAsset(params) {
|
|
|
766
822
|
signal?.removeEventListener('abort', abortFromOperation);
|
|
767
823
|
}
|
|
768
824
|
}
|
|
769
|
-
function sameStringArray(a, b) {
|
|
770
|
-
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
771
|
-
}
|
|
772
|
-
function syncReconcilerEnabled(config) {
|
|
773
|
-
return resolveSyncReconcilerEnabled(config.syncReconcilerEnabled);
|
|
774
|
-
}
|
|
775
|
-
function syncOnConnectEnabled(config) {
|
|
776
|
-
return resolveBooleanSwitch(config.syncOnConnectEnabled, 'DKG_SYNC_ON_CONNECT_ENABLED', true);
|
|
777
|
-
}
|
|
778
|
-
function durableSyncEnabled(config) {
|
|
779
|
-
return resolveBooleanSwitch(config.durableSyncEnabled, 'DKG_DURABLE_SYNC_ENABLED', true);
|
|
780
|
-
}
|
|
781
825
|
/** OT-RFC-59 responder cap on the peer-controlled raw-scan limit (DoS bound). Honest
|
|
782
826
|
* requesters send SYNC_PAGE_SIZE (500); the headroom tolerates larger legitimate pages. */
|
|
783
827
|
const CHANGELOG_MAX_SCAN_LIMIT = 2000;
|
|
784
|
-
function
|
|
785
|
-
return
|
|
786
|
-
}
|
|
787
|
-
function mergeSharedMemorySyncResults(a, b) {
|
|
788
|
-
return {
|
|
789
|
-
...mergeSamePeerSharedMemoryDiagnostics(a, b),
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
function emptySwmRecoveryResult() {
|
|
793
|
-
return {
|
|
794
|
-
replacedRoots: 0,
|
|
795
|
-
replacedGraphs: 0,
|
|
796
|
-
insertedDataQuads: 0,
|
|
797
|
-
insertedMetaQuads: 0,
|
|
798
|
-
droppedDataTriples: 0,
|
|
799
|
-
readySnapshots: 0,
|
|
800
|
-
totalSnapshots: 0,
|
|
801
|
-
completed: true,
|
|
802
|
-
};
|
|
828
|
+
function sameStringArray(a, b) {
|
|
829
|
+
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
803
830
|
}
|
|
804
831
|
export class LifecycleSyncMethods extends DKGAgentBase {
|
|
832
|
+
async retireLegacySwmAfterVerifiedVmTwin(input) {
|
|
833
|
+
await retireRfc64LegacySwmAfterFinalizedVmV1(this, input.contextGraphId, input.kaUal, String(input.assertionVersion), input.subGraphName);
|
|
834
|
+
}
|
|
805
835
|
async retireFinalizedSwmTwinCandidate(candidate, ctx) {
|
|
806
836
|
await this.publisher.clearPublishedKnowledgeAssetSwm(candidate.contextGraphId, {
|
|
807
837
|
kind: 'named-lifecycle',
|
|
@@ -884,6 +914,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
884
914
|
// lanes, and the changelog lane's legacy `runResync` fallback) reports
|
|
885
915
|
// its attempts and bytes under this label without carrying it as a
|
|
886
916
|
// parameter, so it can never reach a coalescing key.
|
|
917
|
+
admission.onWorkStarted?.();
|
|
887
918
|
return await withSyncAdmissionSource(source, work);
|
|
888
919
|
}
|
|
889
920
|
catch (error) {
|
|
@@ -952,6 +983,20 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
952
983
|
admissionBoundary.dispose();
|
|
953
984
|
}
|
|
954
985
|
}
|
|
986
|
+
/**
|
|
987
|
+
* Whether this node's sync admission would take an exact VM recovery fetch
|
|
988
|
+
* for the graph right now. A read of the limiter: nothing is claimed or
|
|
989
|
+
* queued, and the fetch must still handle a refusal.
|
|
990
|
+
*/
|
|
991
|
+
vmRecoverySyncAdmissionAvailable(contextGraphId) {
|
|
992
|
+
return !syncAdmissionWouldBeRefused(resolveAgentSyncGlobalBackpressure(this.config), {
|
|
993
|
+
contextGraphId,
|
|
994
|
+
lane: 'durable',
|
|
995
|
+
priority: VM_RECOVERY_SYNC_PRIORITY,
|
|
996
|
+
priorityClass: syncPriorityClass(VM_RECOVERY_SYNC_PRIORITY),
|
|
997
|
+
source: 'vm-recovery',
|
|
998
|
+
});
|
|
999
|
+
}
|
|
955
1000
|
async start() {
|
|
956
1001
|
if (this.vmReconcileShutdownBlocked) {
|
|
957
1002
|
throw new VmReconcileShutdownTimeoutError(DKGAgentBase.VM_RECONCILE_SHUTDOWN_TIMEOUT_MS);
|
|
@@ -959,6 +1004,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
959
1004
|
if (this.contextGraphMembershipPersistenceShutdownBlocked) {
|
|
960
1005
|
throw new ContextGraphMembershipPersistShutdownTimeoutError(DKGAgentBase.CONTEXT_GRAPH_MEMBERSHIP_PERSIST_SHUTDOWN_TIMEOUT_MS);
|
|
961
1006
|
}
|
|
1007
|
+
if (this.contextGraphSubscriptionPersistenceShutdownBlocked) {
|
|
1008
|
+
throw new ContextGraphSubscriptionPersistShutdownTimeoutError(DKGAgentBase.CONTEXT_GRAPH_SUBSCRIPTION_PERSIST_SHUTDOWN_TIMEOUT_MS);
|
|
1009
|
+
}
|
|
962
1010
|
if (this.started)
|
|
963
1011
|
return;
|
|
964
1012
|
this.storageACKRegistrationRuntime.retireCurrentGeneration();
|
|
@@ -977,9 +1025,13 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
977
1025
|
await this.contextGraphSubscriptionRehydrationPromotionRuntime?.close();
|
|
978
1026
|
this.rfc64BackgroundWorkDispatcherV1.reopen();
|
|
979
1027
|
this.contextGraphMembershipPersistence.reopen();
|
|
1028
|
+
// stop() drained and closed subscription writes; a restarted agent admits
|
|
1029
|
+
// them again. Writes issued before the first start() left it open.
|
|
1030
|
+
this.contextGraphSubscriptionPersistence.reopenIfClosed();
|
|
980
1031
|
// stop() aborts detached cold authority flights; a restarted agent admits
|
|
981
1032
|
// new ones (the runtime is created lazily on first use otherwise).
|
|
982
1033
|
peekFinalizedAuthorityColdResolution(this)?.reopen();
|
|
1034
|
+
peekOnDemandAgentsPhonebook(this)?.reopen();
|
|
983
1035
|
this.vmReconcileRuntimeReady = false;
|
|
984
1036
|
this.graphScopedStoreClosed = false;
|
|
985
1037
|
this.coreHostRecordingGeneration += 1;
|
|
@@ -1090,13 +1142,22 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1090
1142
|
// Move what earlier builds left in ontology, using local metadata only,
|
|
1091
1143
|
// before sync serving starts. Bare bindings of graphs this node doesn't
|
|
1092
1144
|
// hold need a chain read; that pass runs once start completes and before
|
|
1093
|
-
// every store discovery pass.
|
|
1145
|
+
// every store discovery pass. This pass is on the startup path, so it has
|
|
1146
|
+
// a time budget; candidates it doesn't reach are left to those passes.
|
|
1147
|
+
// Until one of them reaches every candidate (this one included), ontology
|
|
1148
|
+
// may still hold private rows, so peers are not served it.
|
|
1094
1149
|
try {
|
|
1095
|
-
await this.relocatePrivateContextGraphMetadata({
|
|
1150
|
+
await this.relocatePrivateContextGraphMetadata({
|
|
1151
|
+
classifyOnChain: false,
|
|
1152
|
+
budgetMs: METADATA_RELOCATION_STARTUP_BUDGET_MS,
|
|
1153
|
+
});
|
|
1096
1154
|
}
|
|
1097
1155
|
catch (err) {
|
|
1098
1156
|
this.log.warn(ctx, `Failed to relocate private context graph metadata out of the ontology graph: ${err instanceof Error ? err.message : String(err)}`);
|
|
1099
1157
|
}
|
|
1158
|
+
if (this.contextGraphServingWithheld(SYSTEM_CONTEXT_GRAPHS.ONTOLOGY)) {
|
|
1159
|
+
this.log.warn(ctx, 'Not serving the ontology graph to peers until the context graph metadata relocation reaches every candidate');
|
|
1160
|
+
}
|
|
1100
1161
|
// Load registered agents from triple store; auto-register default if none exist.
|
|
1101
1162
|
// loadAgentsFromStore restores defaultAgentAddress from the persisted
|
|
1102
1163
|
// isDefaultAgent marker, avoiding reliance on SPARQL result ordering.
|
|
@@ -1273,11 +1334,17 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1273
1334
|
this.messenger.setOutboxResponseHandler(PROTOCOL_JOIN_REQUEST, async (result) => {
|
|
1274
1335
|
await this.handleJoinRequestOutboxResponse(result);
|
|
1275
1336
|
});
|
|
1337
|
+
// Snapshot live intent before any durable read or detached persistence
|
|
1338
|
+
// completion. Durable rows claim their part of this startup plan below.
|
|
1339
|
+
const liveIntents = [...this.subscribedContextGraphs].filter(([, subscription]) => subscription.subscribed && !subscription.pendingMeta);
|
|
1276
1340
|
this.gossip = new GossipSubManager(this.node, this.eventBus, {
|
|
1277
1341
|
networkId: this.config.networkIdentity?.networkId,
|
|
1278
1342
|
chainId: this.config.networkIdentity?.chainId,
|
|
1279
1343
|
isPeerAccepted: (peerId) => this.networkAdmissionCoordinator.isAcceptedPeer(peerId),
|
|
1280
1344
|
});
|
|
1345
|
+
for (const [id, subscription] of liveIntents) {
|
|
1346
|
+
this.gossipSession.startupLiveIntents.set(id, { syncMode: subscription.syncMode });
|
|
1347
|
+
}
|
|
1281
1348
|
await this.loadSwmSenderKeyState();
|
|
1282
1349
|
await this.initializeSwmHostModeStore();
|
|
1283
1350
|
await this.rehydrateContextGraphsFromDurableState();
|
|
@@ -1324,6 +1391,11 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1324
1391
|
// error, so private/curated/unregistered CGs remain denied.
|
|
1325
1392
|
const queryRemoteHandler = new QueryHandler(this.queryEngine, queryAccessConfig, {
|
|
1326
1393
|
isContextGraphPublic: (contextGraphId) => withRpcUsageSite(CG_AUTH_RPC_SITES.remoteQuery, () => this.isContextGraphPublicOnChain(contextGraphId, createOperationContext('query'))),
|
|
1394
|
+
// A graph held back from sync is not queried either, for an operator
|
|
1395
|
+
// whose queryAccess opens it (see contextGraphServingWithheld). The
|
|
1396
|
+
// handler applies this to the id its access policy and lookups use,
|
|
1397
|
+
// once it has checked that id is a string.
|
|
1398
|
+
servingWithheld: (contextGraphId) => this.contextGraphServingWithheld(contextGraphId),
|
|
1327
1399
|
});
|
|
1328
1400
|
// rc.9 PR-9: PROTOCOL_QUERY_REMOTE migrated onto the Universal
|
|
1329
1401
|
// Messenger substrate. Wire prefix bumped to /dkg/10.0.1/* (hard
|
|
@@ -1681,6 +1753,29 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1681
1753
|
await this.handleKARegisteredNudge(onChainId, kaId, ctx, signal);
|
|
1682
1754
|
}
|
|
1683
1755
|
: undefined,
|
|
1756
|
+
// #2858 — refresh nudge for KA updates. An update keeps the KA id and
|
|
1757
|
+
// moves its root, and the sweep never revisits a settled ordinal, so a
|
|
1758
|
+
// node holding only a confirmed VM copy learns of the new version here.
|
|
1759
|
+
// Decided from local state; a V10 KA is its own batch, so the event's
|
|
1760
|
+
// batch id is the KA id. The event's block keeps a chain read that
|
|
1761
|
+
// has not seen the update from settling the refresh, and its
|
|
1762
|
+
// transaction spares a check of the publisher's own copy. A nudge that
|
|
1763
|
+
// fails holds the lane, and the lane never persists its cursor past
|
|
1764
|
+
// an unsettled refresh, so a restart replays that update.
|
|
1765
|
+
onCollectionUpdated: this.vmReconcileEnabled()
|
|
1766
|
+
? async ({ batchId, merkleRoot, blockNumber, txHash, logIndex, blockHash, signal }) => {
|
|
1767
|
+
await this.handleKAUpdatedNudge(batchId, merkleRoot, ctx, {
|
|
1768
|
+
blockNumber,
|
|
1769
|
+
...(txHash === undefined ? {} : { txHash }),
|
|
1770
|
+
...(logIndex === undefined ? {} : { logIndex }),
|
|
1771
|
+
...(blockHash === undefined ? {} : { blockHash }),
|
|
1772
|
+
signal,
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
: undefined,
|
|
1776
|
+
collectionUpdatesPersistCeiling: this.vmReconcileEnabled()
|
|
1777
|
+
? () => this.vmRefreshPersistCeiling()
|
|
1778
|
+
: undefined,
|
|
1684
1779
|
});
|
|
1685
1780
|
await this.chainPoller.start();
|
|
1686
1781
|
this.log.info(ctx, `Chain event poller started`);
|
|
@@ -1853,13 +1948,37 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1853
1948
|
peerId: this.peerId,
|
|
1854
1949
|
parseSyncRequest: this.parseSyncRequest.bind(this),
|
|
1855
1950
|
authorizeSyncRequest: this.authorizeSyncRequest.bind(this),
|
|
1951
|
+
onExperimentalExactBatchResources: resolveExactBatchStreamEnabled()
|
|
1952
|
+
&& this.config.nodeRole === 'core'
|
|
1953
|
+
? (resources) => {
|
|
1954
|
+
const binding = createExactBatchResponderBinding({
|
|
1955
|
+
localPeerId: this.peerId,
|
|
1956
|
+
store: this.store,
|
|
1957
|
+
exportCache: resources.exportCache,
|
|
1958
|
+
admission: resources,
|
|
1959
|
+
parseSyncRequest: this.parseSyncRequest.bind(this),
|
|
1960
|
+
authorizeSyncRequest: this.authorizeSyncRequest.bind(this),
|
|
1961
|
+
isPublicContextGraph: async (cg, signal) => (await this.resolveRegisteredContextGraphAuthority(cg, {
|
|
1962
|
+
authorityReadMode: 'finalized-index-or-live', signal,
|
|
1963
|
+
})).kind === 'public',
|
|
1964
|
+
servingWithheld: (cg) => this.contextGraphServingWithheld(cg),
|
|
1965
|
+
onExport: (assetIndex, wholePayloadExports, operationContext) => this.log.info(operationContext, `Exact batch responder export asset=${assetIndex} wholePayloadExports=${wholePayloadExports}`),
|
|
1966
|
+
onPayload: (assetIndex, plainBytes, encodedBytes, operationContext) => this.log.info(operationContext, `Exact batch responder payload asset=${assetIndex} plainBytes=${plainBytes} encodedBytes=${encodedBytes}`),
|
|
1967
|
+
onFallback: (reason, assetIndex, operationContext, budgetReason) => this.log.info(operationContext, `Exact batch responder refusal asset=${assetIndex} reason=${reason}${budgetReason ? ` budgetReason=${budgetReason}` : ''}`),
|
|
1968
|
+
onStage: (stage, assetIndex, durationMs, operationContext) => this.log.info(operationContext, `Exact batch responder stage=${stage} asset=${assetIndex} durationMs=${durationMs.toFixed(3)}`),
|
|
1969
|
+
});
|
|
1970
|
+
registerExperimentalExactBatchResponder(this.router, exactBatchTransportOptions(120_000), binding.authorizeRequest, binding.respond);
|
|
1971
|
+
}
|
|
1972
|
+
: undefined,
|
|
1856
1973
|
// Serve-skip policy (#1233): withhold the no-consumer agents/_meta snapshot
|
|
1857
1974
|
// unless the operator opts in. This is the env boundary — the pure
|
|
1858
1975
|
// `shouldWithholdAgentsDurableMeta` resolver is called directly with a FRESH
|
|
1859
1976
|
// `process.env.DKG_SERVE_AGENTS_META` read per request, so the kill-switch is
|
|
1860
1977
|
// reversible at runtime (no restart).
|
|
1861
1978
|
shouldWithholdDurableMeta: (contextGraphId) => shouldWithholdAgentsDurableMeta(contextGraphId, process.env.DKG_SERVE_AGENTS_META),
|
|
1979
|
+
servingWithheld: (contextGraphId) => this.contextGraphServingWithheld(contextGraphId),
|
|
1862
1980
|
logWarn: (ctx, message) => this.log.warn(ctx, message),
|
|
1981
|
+
logInfo: (ctx, message) => this.log.info(ctx, message),
|
|
1863
1982
|
logDebug: (ctx, message) => this.log.debug(ctx, message),
|
|
1864
1983
|
snapshotBudget: snapshotPolicy.budget,
|
|
1865
1984
|
contextGraphPriorities: this.config.syncContextGraphPriorities,
|
|
@@ -1965,7 +2084,16 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1965
2084
|
role: 'participant',
|
|
1966
2085
|
status: 'active',
|
|
1967
2086
|
source: 'join-approved',
|
|
1968
|
-
metadata: {
|
|
2087
|
+
metadata: {
|
|
2088
|
+
curatorPeerId: peerId.toString(),
|
|
2089
|
+
// The approved sender's own listener address is a durable
|
|
2090
|
+
// transport hint. An inbound remoteAddr can be an ephemeral
|
|
2091
|
+
// source port, so it is never persisted for restart dialing.
|
|
2092
|
+
...(() => {
|
|
2093
|
+
const address = verifiedCuratorDialAddress(payload.curatorDialAddress, peerId.toString());
|
|
2094
|
+
return address ? { curatorDialAddress: address } : {};
|
|
2095
|
+
})(),
|
|
2096
|
+
},
|
|
1969
2097
|
};
|
|
1970
2098
|
// Commit the restart contract before changing live subscription
|
|
1971
2099
|
// state. The two stores do not expose a shared transaction, so the
|
|
@@ -2229,6 +2357,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2229
2357
|
for (const systemContextGraph of [SYSTEM_CONTEXT_GRAPHS.AGENTS, SYSTEM_CONTEXT_GRAPHS.ONTOLOGY]) {
|
|
2230
2358
|
this.subscribeToContextGraph(systemContextGraph, { syncMode: 'always-on' });
|
|
2231
2359
|
}
|
|
2360
|
+
this.applyStartupContextGraphGossipPlan();
|
|
2232
2361
|
// Connect to bootstrap peers
|
|
2233
2362
|
if (this.config.bootstrapPeers) {
|
|
2234
2363
|
for (const addr of this.config.bootstrapPeers) {
|
|
@@ -2445,6 +2574,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2445
2574
|
// this is now the only outbox tick — chat (PR-3) and every
|
|
2446
2575
|
// future migrated protocol drain on the same cadence so
|
|
2447
2576
|
// operators see a single "outbox tick" beat.
|
|
2577
|
+
let senderKeyRetryInFlight = false;
|
|
2448
2578
|
this.messengerOutboxTimer = setInterval(() => {
|
|
2449
2579
|
const now = Date.now();
|
|
2450
2580
|
this.messenger.processOutboxTick(now)
|
|
@@ -2460,6 +2590,25 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2460
2590
|
`msgId=${entry.messageId.slice(0, 8)} lastError="${entry.lastError}"`);
|
|
2461
2591
|
}
|
|
2462
2592
|
});
|
|
2593
|
+
// A retryable ACK is a delivered Messenger response, so it has no
|
|
2594
|
+
// outbox obligation. The sender-key queue owns that retry and must
|
|
2595
|
+
// progress even if both peers stay connected and no further share is
|
|
2596
|
+
// published. Keep one pass in flight and reuse its current-authority
|
|
2597
|
+
// recipient check before every resend.
|
|
2598
|
+
if (!senderKeyRetryInFlight && this.pendingSenderKeyByAgent.size > 0) {
|
|
2599
|
+
senderKeyRetryInFlight = true;
|
|
2600
|
+
void this.drainPendingSenderKeysForConnectedPeers()
|
|
2601
|
+
.then((drained) => {
|
|
2602
|
+
if (drained > 0) {
|
|
2603
|
+
this.log.info(ctx, `Sender-key retry delivered ${drained} pending package(s)`);
|
|
2604
|
+
}
|
|
2605
|
+
})
|
|
2606
|
+
.catch((err) => {
|
|
2607
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2608
|
+
this.log.warn(ctx, `Sender-key retry tick failed: ${message}`);
|
|
2609
|
+
})
|
|
2610
|
+
.finally(() => { senderKeyRetryInFlight = false; });
|
|
2611
|
+
}
|
|
2463
2612
|
}, MESSAGE_OUTBOX_TICK_MS);
|
|
2464
2613
|
if (this.messengerOutboxTimer.unref)
|
|
2465
2614
|
this.messengerOutboxTimer.unref();
|
|
@@ -2578,6 +2727,12 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2578
2727
|
// Malformed peer bytes → deny (mirrors the legacy lane's parse-fail path).
|
|
2579
2728
|
return encodeChangelogResponse({ kind: 'denied' });
|
|
2580
2729
|
}
|
|
2730
|
+
// A graph held back from the legacy lane is held back here too. The
|
|
2731
|
+
// requester falls back to that lane, which refuses it the same way, and
|
|
2732
|
+
// retries on a later round.
|
|
2733
|
+
if (this.contextGraphServingWithheld(request.contextGraphId)) {
|
|
2734
|
+
throw new QuietRetryableHandlerError(`"${request.contextGraphId}" is not served yet`);
|
|
2735
|
+
}
|
|
2581
2736
|
// Same per-CG gate as PROTOCOL_SYNC: public CGs are open (returns true),
|
|
2582
2737
|
// private CGs verify the signed digest — a bare (unsigned) changelog request
|
|
2583
2738
|
// carries no digest, so `authorizePrivateSyncRequest` denies it. Any throw on a
|
|
@@ -2707,6 +2862,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2707
2862
|
this.warmedCores.delete(remotePeer);
|
|
2708
2863
|
this.warmCoreFailedUnpins.delete(remotePeer);
|
|
2709
2864
|
this.vmReconcileExactPeerCapabilities?.delete(remotePeer);
|
|
2865
|
+
this.vmReconcilePublicCoreTransportPreferencePolicy?.forgetPeer(remotePeer);
|
|
2710
2866
|
}
|
|
2711
2867
|
queueSelectedSwmFromPeerOnConnect(remotePeer, handleSyncError, delayMs = 3000) {
|
|
2712
2868
|
const selectedContextGraphIds = this.selectedSwmBootstrapContextGraphIdsForPeer(remotePeer);
|
|
@@ -2931,7 +3087,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2931
3087
|
const sharedMemoryRecoveryContextGraphIds = [...new Set([
|
|
2932
3088
|
...(this.config.syncContextGraphs ?? []),
|
|
2933
3089
|
...namedSubgraphCompatibilityContextGraphIds,
|
|
2934
|
-
...resolveRfc64PrivateRecoveryContextGraphIdsV1(resolveRfc64RuntimeCatalogBootstrapConfigV1(this.config.rfc64CatalogBootstrap, this.config.rfc64PublicCatalogBootstrap)).filter((contextGraphId) => this.
|
|
3090
|
+
...resolveRfc64PrivateRecoveryContextGraphIdsV1(resolveRfc64RuntimeCatalogBootstrapConfigV1(this.config.rfc64CatalogBootstrap, this.config.rfc64PublicCatalogBootstrap)).filter((contextGraphId) => this.rfc64LegacySwmGossipAllowedForContextGraph(contextGraphId)),
|
|
2935
3091
|
])];
|
|
2936
3092
|
const remotePeerIsCompleteSwmProvider = acceptedPolicies.some(({ completeSwmProviders = [] }) => completeSwmProviders.includes(remotePeer));
|
|
2937
3093
|
const selectedPublicContextGraphIds = new Set(this.selectedSwmBootstrapContextGraphIdsForPeer(remotePeer));
|
|
@@ -2948,11 +3104,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2948
3104
|
getPeerProtocols: (peerId) => this.getPeerProtocols(peerId),
|
|
2949
3105
|
peerCapabilities: this.peerCapabilityRegistry,
|
|
2950
3106
|
getSyncContextGraphs: () => this.config.syncContextGraphs ?? [],
|
|
2951
|
-
getDurableSyncContextGraphs: () => automaticDurableSyncContextGraphs(this.config.syncContextGraphs ?? [], {
|
|
2952
|
-
nodeRole: this.config.nodeRole,
|
|
2953
|
-
configValue: this.config.syncSystemContextGraphsOnConnect,
|
|
2954
|
-
envValue: process.env.DKG_SYNC_SYSTEM_CONTEXT_GRAPHS_ON_CONNECT,
|
|
2955
|
-
}).filter((contextGraphId) => {
|
|
3107
|
+
getDurableSyncContextGraphs: () => automaticDurableSyncContextGraphs(this.config.syncContextGraphs ?? [], systemContextGraphSyncOptionsOf(this.config)).filter((contextGraphId) => {
|
|
2956
3108
|
const completeSwmProviders = this.resolveRfc64CompleteSwmProviderPeerIdsV1(contextGraphId);
|
|
2957
3109
|
// For an RFC-64 selected public CG, VM/durable inventory is chain/core
|
|
2958
3110
|
// territory. An Edge that was pinned as the complete SWM source must
|
|
@@ -3142,10 +3294,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3142
3294
|
this.log.debug(ctx, `Skipping SWM sync for "${contextGraphId}": superseded by cleartext adoption of "${supersedingId}"`);
|
|
3143
3295
|
continue;
|
|
3144
3296
|
}
|
|
3145
|
-
const authority = this.resolveRfc64CatalogReceiverAuthorityV1(contextGraphId);
|
|
3146
3297
|
const completeSwmProviders = this.resolveRfc64CompleteSwmProviderPeerIdsV1(contextGraphId);
|
|
3147
3298
|
const acceptedRecoveryLane = resolveRfc64SwmRecoveryLaneV1(resolveRfc64RuntimeCatalogBootstrapConfigV1(this.config.rfc64CatalogBootstrap, this.config.rfc64PublicCatalogBootstrap), contextGraphId);
|
|
3148
|
-
const legacyRootSyncAllowed =
|
|
3299
|
+
const legacyRootSyncAllowed = this.rfc64LegacySwmGossipAllowedForContextGraph(contextGraphId);
|
|
3149
3300
|
const namedSubgraphCompatibilityRequired = !legacyRootSyncAllowed
|
|
3150
3301
|
&& this.subscribedContextGraphs.get(contextGraphId)?.subscribed === true;
|
|
3151
3302
|
if (!legacyRootSyncAllowed && !namedSubgraphCompatibilityRequired) {
|
|
@@ -3253,7 +3404,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3253
3404
|
* leaves a peer permanently in `skippedNoSyncPeers`. libp2p emits
|
|
3254
3405
|
* `peer:update` whenever a peer record changes — most importantly when
|
|
3255
3406
|
* identify completes and the protocol list gets populated for the
|
|
3256
|
-
* first time. If the new list now contains
|
|
3407
|
+
* first time. If the new list now contains either sync id and we
|
|
3257
3408
|
* previously skipped this peer for that exact reason, fire one
|
|
3258
3409
|
* `trySyncFromPeer` immediately.
|
|
3259
3410
|
*
|
|
@@ -3283,7 +3434,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3283
3434
|
return;
|
|
3284
3435
|
if (!syncOnConnectEnabled(this.config))
|
|
3285
3436
|
return;
|
|
3286
|
-
if (!protocols
|
|
3437
|
+
if (!advertisesSyncProtocol(protocols))
|
|
3287
3438
|
return;
|
|
3288
3439
|
const ctx = createOperationContext('sync');
|
|
3289
3440
|
void peerEvents.run(() => this.retrySyncAfterPeerUpdate(peerId, ctx, peerEvents), (error) => this.log.warn(ctx, `Sync retry after peer:update failed for ${peerId.slice(-8)}: ${error instanceof Error ? error.message : String(error)}`));
|
|
@@ -3305,7 +3456,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3305
3456
|
* Periodic reconciler for sync-on-connect. Walks every currently
|
|
3306
3457
|
* connected peer and retries `trySyncFromPeer` for any that either:
|
|
3307
3458
|
*
|
|
3308
|
-
* - is in {@link skippedNoSyncPeers} and now advertises
|
|
3459
|
+
* - is in {@link skippedNoSyncPeers} and now advertises either sync id
|
|
3309
3460
|
* (covers the case where the `peer:update` listener missed the
|
|
3310
3461
|
* event for whatever reason), or
|
|
3311
3462
|
* - has no recent clean success or useful-progress cooldown marker, or
|
|
@@ -3524,13 +3675,14 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3524
3675
|
const isShardingTableMember = this.chain.isShardingTableMember?.bind(this.chain);
|
|
3525
3676
|
if (!getIdentityIdForAddress || !isShardingTableMember)
|
|
3526
3677
|
return true; // gate unavailable
|
|
3527
|
-
//
|
|
3528
|
-
//
|
|
3529
|
-
//
|
|
3530
|
-
//
|
|
3531
|
-
//
|
|
3678
|
+
// Profiles are unsigned: a `nodeRole='core'` profile without an
|
|
3679
|
+
// operational wallet cannot be checked against the ShardingTable, so it is
|
|
3680
|
+
// as unverifiable as a failed read and is not pinned. Every profile this
|
|
3681
|
+
// codebase publishes carries `agentAddress`; on Base mainnet (2026-09-23)
|
|
3682
|
+
// 62 of 63 core-role profiles did, and the one that did not was pinned and
|
|
3683
|
+
// then failed its dial on every tick.
|
|
3532
3684
|
if (!agentAddress)
|
|
3533
|
-
return
|
|
3685
|
+
return false;
|
|
3534
3686
|
try {
|
|
3535
3687
|
const identityId = await getIdentityIdForAddress(agentAddress);
|
|
3536
3688
|
if (identityId === 0n)
|
|
@@ -3669,6 +3821,27 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3669
3821
|
const result = await this.syncFromPeerDetailed(remotePeerId, contextGraphIds, onPhase, onAccessDenied, undefined, options);
|
|
3670
3822
|
return result.insertedTriples;
|
|
3671
3823
|
}
|
|
3824
|
+
/** One agent-owned admission decision for the legacy shared-memory lane. */
|
|
3825
|
+
async canUseLegacySharedMemorySyncForContextGraphV1(contextGraphId) {
|
|
3826
|
+
// The private predicate verifies local membership and current lane authority.
|
|
3827
|
+
return this.rfc64LegacySwmGossipAllowedForContextGraph(contextGraphId)
|
|
3828
|
+
|| await this.rfc64PrivateRootSwmOnLegacyLaneV1(contextGraphId) === true;
|
|
3829
|
+
}
|
|
3830
|
+
/** One agent-owned admission decision for the legacy durable VM lane. */
|
|
3831
|
+
async canUseLegacyDurableSyncForContextGraphV1(contextGraphId) {
|
|
3832
|
+
// The global emergency stop restores the legacy VM lane even for a
|
|
3833
|
+
// selected catalog graph whose persisted receiver policy remains catalog.
|
|
3834
|
+
if (this.config.rfc64CatalogExecutionPlan.killSwitchActive)
|
|
3835
|
+
return true;
|
|
3836
|
+
if (this.resolveRfc64CatalogReceiverAuthorityV1(contextGraphId).legacySyncAllowed) {
|
|
3837
|
+
return true;
|
|
3838
|
+
}
|
|
3839
|
+
// An approved private member keeps this compatibility lane while its
|
|
3840
|
+
// RFC-64 private receiver authority is inactive. The predicate performs
|
|
3841
|
+
// the authenticated local member proof; outsiders remain excluded.
|
|
3842
|
+
return typeof this.rfc64PrivateRootSwmOnLegacyLaneV1 === 'function'
|
|
3843
|
+
&& await this.rfc64PrivateRootSwmOnLegacyLaneV1(contextGraphId) === true;
|
|
3844
|
+
}
|
|
3672
3845
|
async syncFromPeerDetailed(remotePeerId, contextGraphIds, onPhase, onAccessDenied,
|
|
3673
3846
|
// Phase C — optional gap-safe per-CG delta high-water mark resolver. Backed
|
|
3674
3847
|
// by a CONTIGUOUS watermark when supplied; omitted ⇒ full scan (default).
|
|
@@ -3679,7 +3852,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3679
3852
|
return createIncompleteDurableSyncResult();
|
|
3680
3853
|
}
|
|
3681
3854
|
const requestedContextGraphCount = contextGraphIds.length;
|
|
3682
|
-
|
|
3855
|
+
const legacyDurableAllowed = await Promise.all(contextGraphIds.map((contextGraphId) => LifecycleSyncMethods.prototype.canUseLegacyDurableSyncForContextGraphV1.call(this, contextGraphId)));
|
|
3856
|
+
contextGraphIds = contextGraphIds.filter((_, index) => legacyDurableAllowed[index]);
|
|
3683
3857
|
if (contextGraphIds.length !== requestedContextGraphCount) {
|
|
3684
3858
|
this.log.debug(ctx, `Skipped ${requestedContextGraphCount - contextGraphIds.length} catalog-authoritative CG(s) from legacy durable sync`);
|
|
3685
3859
|
}
|
|
@@ -3735,6 +3909,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3735
3909
|
return (await LifecycleSyncMethods.prototype.runLegacyDurableSyncDetailed.call(this, ctx, remotePeerId, contextGraphIds, onPhase, onAccessDenied, sinceBatchIdFor, options)).result;
|
|
3736
3910
|
}
|
|
3737
3911
|
async runLegacyDurableSyncDetailed(ctx, remotePeerId, contextGraphIds, onPhase, onAccessDenied, sinceBatchIdFor, options) {
|
|
3912
|
+
const admissionBoundary = new DurableSyncAdmissionBoundary(options?.onWorkStarted);
|
|
3738
3913
|
const syncAgentsMeta = resolveSyncAgentsMeta(this.config.syncAgentsMeta, process.env.DKG_SYNC_AGENTS_META);
|
|
3739
3914
|
const stopOnBackoffWorthyFailure = options?.stopOnBackoffWorthyFailure;
|
|
3740
3915
|
const exactAssetSelection = options?.exactAssetSelection;
|
|
@@ -3760,6 +3935,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3760
3935
|
let exactFetchDisposition;
|
|
3761
3936
|
let exactResponderCapability;
|
|
3762
3937
|
const authenticatedExactAssets = [];
|
|
3938
|
+
const committedExactAssetUals = [];
|
|
3939
|
+
// What the stream established about this peer for one graph. A run over
|
|
3940
|
+
// several graphs has no single answer, so it reports none.
|
|
3941
|
+
let exactStreamOutcome;
|
|
3763
3942
|
const markExactFetchIncomplete = () => {
|
|
3764
3943
|
if (exactAssetUals === undefined)
|
|
3765
3944
|
return;
|
|
@@ -3780,6 +3959,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3780
3959
|
stopOnBackoffWorthyFailure,
|
|
3781
3960
|
fetchTimeoutMs,
|
|
3782
3961
|
exactAssetSelection,
|
|
3962
|
+
forceFreshExactSession: options?.forceFreshExactSession,
|
|
3963
|
+
exactRecoveryTransportMode: options?.exactRecoveryTransportMode,
|
|
3964
|
+
registeredPublicEvidence: options?.registeredPublicEvidence,
|
|
3783
3965
|
authenticationTimeoutMs,
|
|
3784
3966
|
operationFetchDeadline: operationBoundary.fetchDeadline,
|
|
3785
3967
|
operationDeadline: operationBoundary.deadline,
|
|
@@ -3795,6 +3977,11 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3795
3977
|
if (detailed.authenticatedExactAssets !== undefined) {
|
|
3796
3978
|
authenticatedExactAssets.push(...detailed.authenticatedExactAssets);
|
|
3797
3979
|
}
|
|
3980
|
+
if (detailed.committedExactAssetUals !== undefined) {
|
|
3981
|
+
committedExactAssetUals.push(...detailed.committedExactAssetUals);
|
|
3982
|
+
}
|
|
3983
|
+
if (orderedContextGraphIds.length === 1)
|
|
3984
|
+
exactStreamOutcome = detailed.exactStreamOutcome;
|
|
3798
3985
|
return durableSyncAccumulatorFromResult(detailed.result);
|
|
3799
3986
|
},
|
|
3800
3987
|
})),
|
|
@@ -3806,6 +3993,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3806
3993
|
priorityOverride: options?.priority,
|
|
3807
3994
|
operationSignal: operationBoundary.signal,
|
|
3808
3995
|
source: options?.source,
|
|
3996
|
+
onWorkStarted: admissionBoundary.startWork,
|
|
3809
3997
|
}), operationBoundary.signal);
|
|
3810
3998
|
}
|
|
3811
3999
|
catch (error) {
|
|
@@ -3817,6 +4005,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3817
4005
|
},
|
|
3818
4006
|
merge: mergeDurableSyncAccumulatorInto,
|
|
3819
4007
|
markDeferred: (summary) => {
|
|
4008
|
+
admissionBoundary.defer();
|
|
3820
4009
|
markExactFetchIncomplete();
|
|
3821
4010
|
recordDurableSyncDiagnostics(summary, { deferredBackpressure: 1 });
|
|
3822
4011
|
return markDurableTerminalBoundary(summary, false);
|
|
@@ -3839,12 +4028,17 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3839
4028
|
onDeferred: (item, error) => this.log.info(ctx, `Deferring durable sync at CG ${item.contextGraphId} due to local backpressure: ${error.message}`),
|
|
3840
4029
|
});
|
|
3841
4030
|
return {
|
|
4031
|
+
admission: admissionBoundary.snapshot(),
|
|
3842
4032
|
result: finalizeDurableSyncCompletion(accumulator),
|
|
3843
4033
|
...(exactFetchDisposition ? { exactFetchDisposition } : {}),
|
|
3844
4034
|
...(exactResponderCapability ? { exactResponderCapability } : {}),
|
|
3845
4035
|
...(authenticatedExactAssets.length === 0
|
|
3846
4036
|
? {}
|
|
3847
4037
|
: { authenticatedExactAssets: Object.freeze([...authenticatedExactAssets]) }),
|
|
4038
|
+
...(committedExactAssetUals.length === 0
|
|
4039
|
+
? {}
|
|
4040
|
+
: { committedExactAssetUals: Object.freeze([...committedExactAssetUals]) }),
|
|
4041
|
+
...(exactStreamOutcome === undefined ? {} : { exactStreamOutcome }),
|
|
3848
4042
|
};
|
|
3849
4043
|
};
|
|
3850
4044
|
const singleFlightKey = durableSyncSingleFlightKey({
|
|
@@ -3856,13 +4050,17 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3856
4050
|
syncAgentsMeta,
|
|
3857
4051
|
hasPhaseCallback: Boolean(onPhase),
|
|
3858
4052
|
hasAtomicCommitCallback: Boolean(options?.onAtomicCommitStarted),
|
|
4053
|
+
hasWorkStartedCallback: Boolean(options?.onWorkStarted),
|
|
3859
4054
|
hasAccessDeniedCallback: Boolean(onAccessDenied),
|
|
3860
4055
|
hasSinceBatchIdResolver: Boolean(sinceBatchIdFor),
|
|
3861
4056
|
hasSignal: Boolean(operationBoundary.signal),
|
|
3862
4057
|
hasCurrentFence: Boolean(options?.isCurrent),
|
|
3863
4058
|
hasChallengePinnedSelection: exactAssetSelection?.kind === 'challenge-pinned',
|
|
4059
|
+
hasForcedFreshExactSession: options?.forceFreshExactSession === true,
|
|
4060
|
+
hasRegisteredPublicEvidence: options?.registeredPublicEvidence !== undefined,
|
|
3864
4061
|
exactAssetUals,
|
|
3865
4062
|
settlementSliceTimeoutMs: options?.settlementSliceTimeoutMs,
|
|
4063
|
+
exactRecoveryTransportMode: options?.exactRecoveryTransportMode,
|
|
3866
4064
|
priority: options?.priority,
|
|
3867
4065
|
});
|
|
3868
4066
|
const runWithinBoundary = async () => {
|
|
@@ -3893,13 +4091,19 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3893
4091
|
const ctx = createOperationContext('sync');
|
|
3894
4092
|
const detailed = await this.runLegacyDurableSyncDetailed(ctx, remotePeerId, [contextGraphId], undefined, undefined, undefined, {
|
|
3895
4093
|
exactAssetSelection: selection,
|
|
4094
|
+
forceFreshExactSession: options.forceFreshExactSession,
|
|
4095
|
+
exactRecoveryTransportMode: options.exactRecoveryTransportMode,
|
|
4096
|
+
registeredPublicEvidence: options.registeredPublicEvidence,
|
|
4097
|
+
...(options.totalTimeoutMs === undefined ? {} : { totalTimeoutMs: options.totalTimeoutMs }),
|
|
3896
4098
|
stopOnBackoffWorthyFailure: true,
|
|
3897
|
-
priority:
|
|
4099
|
+
priority: VM_RECOVERY_SYNC_PRIORITY,
|
|
3898
4100
|
source: 'vm-recovery',
|
|
4101
|
+
onWorkStarted: options.onWorkStarted,
|
|
3899
4102
|
signal: options.signal,
|
|
3900
4103
|
isCurrent: options.isCurrent,
|
|
3901
4104
|
});
|
|
3902
4105
|
return {
|
|
4106
|
+
admission: detailed.admission,
|
|
3903
4107
|
result: detailed.result,
|
|
3904
4108
|
disposition: detailed.exactFetchDisposition ?? 'incomplete',
|
|
3905
4109
|
...(detailed.exactResponderCapability === undefined
|
|
@@ -3908,14 +4112,30 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3908
4112
|
...(detailed.authenticatedExactAssets === undefined
|
|
3909
4113
|
? {}
|
|
3910
4114
|
: { authenticatedAssets: detailed.authenticatedExactAssets }),
|
|
4115
|
+
...(detailed.committedExactAssetUals === undefined
|
|
4116
|
+
? {}
|
|
4117
|
+
: { committedExactAssetUals: detailed.committedExactAssetUals }),
|
|
4118
|
+
...(detailed.exactStreamOutcome === undefined
|
|
4119
|
+
? {}
|
|
4120
|
+
: { streamOutcome: detailed.exactStreamOutcome }),
|
|
3911
4121
|
};
|
|
3912
4122
|
}
|
|
3913
4123
|
/** Execute one legacy durable Context Graph after its caller owns admission. */
|
|
3914
4124
|
async runLegacyDurableSyncForContextGraph(ctx, remotePeerId, contextGraphId, remainingContextGraphs, options = {}) {
|
|
3915
4125
|
return (await LifecycleSyncMethods.prototype.runLegacyDurableSyncForContextGraphDetailed.call(this, ctx, remotePeerId, contextGraphId, remainingContextGraphs, options)).result;
|
|
3916
4126
|
}
|
|
4127
|
+
/** Capture transport refusal scope without performing authority or store IO. */
|
|
4128
|
+
captureExperimentalExactBatchRefusalScope(contextGraphId) {
|
|
4129
|
+
return captureExactBatchStreamRefusalScope({
|
|
4130
|
+
contextGraphId, deploymentId: this.chain.deploymentId,
|
|
4131
|
+
binding: this.contextGraphBindingState.currentBindingFor(contextGraphId, this.subscribedContextGraphs.get(contextGraphId)),
|
|
4132
|
+
bindingGeneration: this.contextGraphBindingState.capture(contextGraphId),
|
|
4133
|
+
selectedBindingGeneration: this.selectedVmReconcileCursors?.get(contextGraphId)?.bindingGeneration,
|
|
4134
|
+
lifecycleGeneration: this.vmReconcileLifecycleGeneration,
|
|
4135
|
+
});
|
|
4136
|
+
}
|
|
3917
4137
|
async runLegacyDurableSyncForContextGraphDetailed(ctx, remotePeerId, contextGraphId, remainingContextGraphs, options = {}) {
|
|
3918
|
-
const { onPhase, onAtomicCommitStarted, onAccessDenied, sinceBatchIdFor, stopOnBackoffWorthyFailure, onVerifiedFullSnapshot, fetchTimeoutMs = SYNC_TOTAL_TIMEOUT_MS, exactAssetSelection, authenticationTimeoutMs = fetchTimeoutMs, operationFetchDeadline, operationDeadline, settlementSliceTimeoutMs, signal, isCurrent, durableMetaContinuation, } = options;
|
|
4138
|
+
const { onPhase, onAtomicCommitStarted, onAccessDenied, sinceBatchIdFor, stopOnBackoffWorthyFailure, onVerifiedFullSnapshot, fetchTimeoutMs = SYNC_TOTAL_TIMEOUT_MS, exactAssetSelection, forceFreshExactSession, exactRecoveryTransportMode = 'stream-preferred', registeredPublicEvidence, authenticationTimeoutMs = fetchTimeoutMs, operationFetchDeadline, operationDeadline, settlementSliceTimeoutMs, signal, isCurrent, durableMetaContinuation, } = options;
|
|
3919
4139
|
const assertLifecycleCurrent = () => {
|
|
3920
4140
|
if (isCurrent?.() === false) {
|
|
3921
4141
|
throw asSyncFetchAbortError(new Error(`Exact VM recovery lifecycle for ${contextGraphId} is no longer current`));
|
|
@@ -3995,6 +4215,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
3995
4215
|
sinceBatchId,
|
|
3996
4216
|
signal: fetchContext.signal,
|
|
3997
4217
|
forceFreshSession: forceFreshSession
|
|
4218
|
+
|| forceFreshExactSession === true
|
|
3998
4219
|
|| onVerifiedFullSnapshot !== undefined,
|
|
3999
4220
|
manifestDigest,
|
|
4000
4221
|
manifestPrefixDigestAtOffset,
|
|
@@ -4074,7 +4295,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4074
4295
|
+ `${subscription.onChainId}`), { code: 'VM_CHAIN_CONTEXT_GRAPH_MISMATCH' });
|
|
4075
4296
|
}
|
|
4076
4297
|
if (verifiedOnChainId && subscription && subscription.onChainId === undefined) {
|
|
4077
|
-
|
|
4298
|
+
// An on-demand subscription binds in memory only; durable rows are
|
|
4299
|
+
// saved before the binding becomes visible.
|
|
4300
|
+
await this.persistContextGraphSyncStateStrict(asset.contextGraphId, { ...subscription, onChainId: verifiedOnChainId, lastReconciledOrdinal: 0 }, 'on-chain id binding', isBindingCurrent);
|
|
4078
4301
|
assertCurrent();
|
|
4079
4302
|
this.bindSubscriptionOnChainId(asset.contextGraphId, subscription, verifiedOnChainId);
|
|
4080
4303
|
recaptureBindingGeneration();
|
|
@@ -4107,13 +4330,26 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4107
4330
|
this.invalidateListContextGraphsCache();
|
|
4108
4331
|
this.contextGraphMetaProjection.markDirtyFromQuads(authentication.asset.metadataQuads);
|
|
4109
4332
|
try {
|
|
4333
|
+
let retiredTwin;
|
|
4110
4334
|
const retirement = await reconcileFinalizedSwmTwin({
|
|
4111
4335
|
store: this.store,
|
|
4112
4336
|
writeLocks: this.writeLocks,
|
|
4113
4337
|
asset: authentication.asset,
|
|
4114
|
-
retire: (candidate) =>
|
|
4338
|
+
retire: async (candidate) => {
|
|
4339
|
+
await this.retireFinalizedSwmTwinCandidate(candidate, ctx);
|
|
4340
|
+
retiredTwin = candidate;
|
|
4341
|
+
},
|
|
4115
4342
|
});
|
|
4116
4343
|
if (retirement === 'retired') {
|
|
4344
|
+
await this.retireLegacySwmAfterVerifiedVmTwin({
|
|
4345
|
+
contextGraphId: asset.contextGraphId,
|
|
4346
|
+
kaUal: asset.ual,
|
|
4347
|
+
assertionVersion: asset.assertionVersion,
|
|
4348
|
+
// The marker of the namespace whose twin was verified and
|
|
4349
|
+
// retired. Without it a twin in a named subgraph would
|
|
4350
|
+
// retire the root marker of the same asset.
|
|
4351
|
+
subGraphName: retiredTwin?.subGraphName,
|
|
4352
|
+
});
|
|
4117
4353
|
this.invalidateListContextGraphsCache();
|
|
4118
4354
|
this.log.info(ctx, `Retired byte-identical SWM twin after durable VM materialization for ${asset.ual}`);
|
|
4119
4355
|
}
|
|
@@ -4161,7 +4397,54 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4161
4397
|
};
|
|
4162
4398
|
}
|
|
4163
4399
|
if (exactAssetSelection !== undefined) {
|
|
4164
|
-
|
|
4400
|
+
const outcome = await runExactBatchStreamDriver({
|
|
4401
|
+
contextGraphId, remotePeerId,
|
|
4402
|
+
selection: exactAssetSelection, transportMode: exactRecoveryTransportMode,
|
|
4403
|
+
streamEnabled: resolveExactBatchStreamEnabled(),
|
|
4404
|
+
fetchDeadline: contextGraphBudget.fetchDeadline, signal, isCurrent,
|
|
4405
|
+
}, {
|
|
4406
|
+
router: this.router, capabilityOwner: this,
|
|
4407
|
+
captureConnectionKey: () => this.getSyncReconcilerConnectionKey(remotePeerId),
|
|
4408
|
+
captureRefusalScope: () => this.captureExperimentalExactBatchRefusalScope(contextGraphId),
|
|
4409
|
+
isChainEnabled: () => this.chain.chainId !== 'none',
|
|
4410
|
+
getPeerProtocols: () => this.getPeerProtocols(remotePeerId),
|
|
4411
|
+
// The recovery pass that owns this exchange may have handed it its own fresh positive
|
|
4412
|
+
// answer; every other fetch, and any doubt about that answer, reads the authority itself.
|
|
4413
|
+
isRegisteredPublic: async () => registeredPublicEvidence?.usableFor(contextGraphId, signal) === true
|
|
4414
|
+
|| (await this.resolveRegisteredContextGraphAuthority(contextGraphId, {
|
|
4415
|
+
authorityReadMode: 'finalized-index-or-live', signal,
|
|
4416
|
+
})).kind === 'public',
|
|
4417
|
+
requestIdentity: () => ({
|
|
4418
|
+
requesterPeerId: this.peerId,
|
|
4419
|
+
computeSyncDigest: (...args) => this.computeSyncDigest(...args),
|
|
4420
|
+
getIdentityId: () => this.chain.getIdentityId(),
|
|
4421
|
+
signMessage: typeof this.chain.signMessage === 'function' ? this.chain.signMessage.bind(this.chain) : undefined,
|
|
4422
|
+
}),
|
|
4423
|
+
verification: {
|
|
4424
|
+
ctx,
|
|
4425
|
+
parseAndFilter: (text, graph, cg) => this.getOrCreateSyncVerifyWorker().parseAndFilter(text, graph, cg),
|
|
4426
|
+
processDurableBatchInWorker: durableContext.processDurableBatchInWorker,
|
|
4427
|
+
authenticationDeadline: contextGraphBudget.createGraphScopedAuthenticationDeadline,
|
|
4428
|
+
storeGraphScopedAsset: durableContext.storeGraphScopedAsset,
|
|
4429
|
+
},
|
|
4430
|
+
reconnect: async (reconnectSignal) => {
|
|
4431
|
+
try {
|
|
4432
|
+
await this.ensurePeerConnected(remotePeerId, { signal: reconnectSignal });
|
|
4433
|
+
}
|
|
4434
|
+
catch {
|
|
4435
|
+
// Unreachable for now, or connected but no longer admitted.
|
|
4436
|
+
return false;
|
|
4437
|
+
}
|
|
4438
|
+
return this.node.libp2p.getConnections()
|
|
4439
|
+
.some((connection) => connection.remotePeer.toString() === remotePeerId);
|
|
4440
|
+
},
|
|
4441
|
+
logInfo: message => this.log.info(ctx, message),
|
|
4442
|
+
});
|
|
4443
|
+
switch (outcome.kind) {
|
|
4444
|
+
case 'settled': return outcome.detailed;
|
|
4445
|
+
case 'not-selected':
|
|
4446
|
+
case 'unsupported-before-start': return runDurableSyncDetailed(durableContext);
|
|
4447
|
+
}
|
|
4165
4448
|
}
|
|
4166
4449
|
return { result: await runDurableSync(durableContext) };
|
|
4167
4450
|
}
|
|
@@ -4510,9 +4793,25 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4510
4793
|
deadline,
|
|
4511
4794
|
fetchSharingIdentity: defaultPageFetchSharingIdentity,
|
|
4512
4795
|
});
|
|
4796
|
+
// Match the additive builder negotiation. Authorization is still evaluated
|
|
4797
|
+
// by buildSyncRequest and by the responder before any export is admitted.
|
|
4798
|
+
const responseEncoding = resolveExactSyncGzipProfile({
|
|
4799
|
+
includeSharedMemory, phase, assetUals, responseEncoding: EXACT_SYNC_GZIP_ENCODING,
|
|
4800
|
+
})?.responseEncoding;
|
|
4513
4801
|
const exactAccumulationLimits = assetUals === undefined
|
|
4514
4802
|
? undefined
|
|
4515
|
-
: exactSyncPhaseAccumulationLimits(assetUals);
|
|
4803
|
+
: exactSyncPhaseAccumulationLimits(assetUals, responseEncoding);
|
|
4804
|
+
const effectiveMaxAcceptedQuads = exactAccumulationLimits?.maxQuads === undefined
|
|
4805
|
+
? maxAcceptedQuads
|
|
4806
|
+
: maxAcceptedQuads === undefined
|
|
4807
|
+
? exactAccumulationLimits.maxQuads
|
|
4808
|
+
: Math.min(exactAccumulationLimits.maxQuads, maxAcceptedQuads);
|
|
4809
|
+
const exactHeapLimit = exactAccumulationLimits?.maxHeapBytesEstimate;
|
|
4810
|
+
const effectiveMaxAcceptedHeapBytesEstimate = exactHeapLimit === undefined
|
|
4811
|
+
? maxAcceptedHeapBytesEstimate
|
|
4812
|
+
: maxAcceptedHeapBytesEstimate === undefined
|
|
4813
|
+
? exactHeapLimit
|
|
4814
|
+
: Math.min(exactHeapLimit, maxAcceptedHeapBytesEstimate);
|
|
4516
4815
|
// Coalescing is declared by the capability, never inferred from singleton
|
|
4517
4816
|
// identity. Exclusive private rounds cannot inherit another job's clock.
|
|
4518
4817
|
const fetchSharingIdentity = effectiveWorkAdmission.fetchSharingIdentity;
|
|
@@ -4532,8 +4831,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4532
4831
|
assetUals,
|
|
4533
4832
|
returnAcceptedPrefixOnRetryableTransportFailure,
|
|
4534
4833
|
requesterScope,
|
|
4535
|
-
|
|
4536
|
-
|
|
4834
|
+
responseEncoding,
|
|
4835
|
+
maxAcceptedBytes: exactAccumulationLimits?.maxBytes,
|
|
4836
|
+
maxAcceptedQuads: effectiveMaxAcceptedQuads,
|
|
4837
|
+
maxAcceptedHeapBytesEstimate: effectiveMaxAcceptedHeapBytesEstimate,
|
|
4537
4838
|
});
|
|
4538
4839
|
const inFlight = inFlightSyncPageFetchesFor(this);
|
|
4539
4840
|
// Read once, here: this fetch runs inside the admitted operation, so the
|
|
@@ -4590,15 +4891,12 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4590
4891
|
snapshotRef,
|
|
4591
4892
|
sinceBatchId,
|
|
4592
4893
|
assetUals,
|
|
4894
|
+
responseEncoding,
|
|
4593
4895
|
returnAcceptedPrefixOnRetryableTransportFailure,
|
|
4594
4896
|
requesterScope,
|
|
4595
4897
|
maxAcceptedBytes: exactAccumulationLimits?.maxBytes,
|
|
4596
|
-
maxAcceptedQuads:
|
|
4597
|
-
|
|
4598
|
-
: maxAcceptedQuads === undefined
|
|
4599
|
-
? exactAccumulationLimits.maxQuads
|
|
4600
|
-
: Math.min(exactAccumulationLimits.maxQuads, maxAcceptedQuads),
|
|
4601
|
-
maxAcceptedHeapBytesEstimate,
|
|
4898
|
+
maxAcceptedQuads: effectiveMaxAcceptedQuads,
|
|
4899
|
+
maxAcceptedHeapBytesEstimate: effectiveMaxAcceptedHeapBytesEstimate,
|
|
4602
4900
|
pageSizeProfileCache: syncPageSizeProfileCacheFor(this),
|
|
4603
4901
|
deadline,
|
|
4604
4902
|
recovery,
|
|
@@ -4861,11 +5159,12 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4861
5159
|
return execution(emptySharedMemorySyncResult());
|
|
4862
5160
|
}
|
|
4863
5161
|
const recoveryExecutor = this.createSwmTargetExecutorSessionV1();
|
|
4864
|
-
const recoverPrivateContextGraph = (contextGraphId, recoveryLease, onRetry) => recoveryExecutor.recoverPrivateTarget({
|
|
5162
|
+
const recoverPrivateContextGraph = async (contextGraphId, recoveryLease, onRetry) => recoveryExecutor.recoverPrivateTarget({
|
|
4865
5163
|
remotePeerId,
|
|
4866
5164
|
contextGraphId,
|
|
4867
5165
|
includeRootScope: requestedScope !== null
|
|
4868
|
-
|| this.
|
|
5166
|
+
|| this.rfc64LegacySwmGossipAllowedForContextGraph(contextGraphId)
|
|
5167
|
+
|| await this.rfc64PrivateRootSwmOnLegacyLaneV1(contextGraphId),
|
|
4869
5168
|
recoveryGuard: recoveryLease,
|
|
4870
5169
|
onRetry,
|
|
4871
5170
|
});
|
|
@@ -4972,7 +5271,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4972
5271
|
contextGraphId,
|
|
4973
5272
|
remainingContextGraphs,
|
|
4974
5273
|
includeRootScope: requestedScope !== null
|
|
4975
|
-
|| this.
|
|
5274
|
+
|| this.rfc64LegacySwmGossipAllowedForContextGraph(contextGraphId),
|
|
4976
5275
|
stopOnBackoffWorthyFailure,
|
|
4977
5276
|
mode,
|
|
4978
5277
|
});
|
|
@@ -5047,7 +5346,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5047
5346
|
selectedSwmPriority: selectedPublicWork,
|
|
5048
5347
|
});
|
|
5049
5348
|
},
|
|
5050
|
-
merge:
|
|
5349
|
+
merge: mergeSamePeerSharedMemoryDiagnostics,
|
|
5051
5350
|
onResult: (item, result) => {
|
|
5052
5351
|
if (selectedSwmEnabled
|
|
5053
5352
|
&& item.lane === 'shared_memory'
|
|
@@ -5101,7 +5400,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5101
5400
|
source: options?.source,
|
|
5102
5401
|
selectedSwmPriority: true,
|
|
5103
5402
|
}),
|
|
5104
|
-
merge:
|
|
5403
|
+
merge: mergeSamePeerSharedMemoryDiagnostics,
|
|
5105
5404
|
markDeferred: (summary) => ({
|
|
5106
5405
|
...summary,
|
|
5107
5406
|
deferredBackpressure: (summary.deferredBackpressure ?? 0) + 1,
|
|
@@ -5124,7 +5423,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5124
5423
|
},
|
|
5125
5424
|
});
|
|
5126
5425
|
const { summary: continuationSummary } = continuationExecution;
|
|
5127
|
-
const finalSummary =
|
|
5426
|
+
const finalSummary = mergeSamePeerSharedMemoryDiagnostics(initialSummary, continuationSummary);
|
|
5128
5427
|
const incompleteSelectedContextGraphs = new Set(continuationExecution.incompleteContextGraphIds);
|
|
5129
5428
|
const continuedSelectedContextGraphs = new Set(selectedContinuationUnits.map(({ work: unitWork }) => unitWork.contextGraphId));
|
|
5130
5429
|
for (const target of selectedPublicTargets) {
|
|
@@ -5164,11 +5463,14 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5164
5463
|
this.log.warn(ctx, `Skipping SWM recovery from ${remotePeerId.slice(-8)} (DKG_DURABLE_SYNC_ENABLED=0)`);
|
|
5165
5464
|
return emptySwmRecoveryResult();
|
|
5166
5465
|
}
|
|
5167
|
-
return this.runContextGraphSyncWithBackpressure(ctx, contextGraphId, 'swm_recovery', `swm-recovery:${contextGraphId}:${remotePeerId.slice(-8)}`, () => this.createSwmTargetExecutorSessionV1()
|
|
5466
|
+
return this.runContextGraphSyncWithBackpressure(ctx, contextGraphId, 'swm_recovery', `swm-recovery:${contextGraphId}:${remotePeerId.slice(-8)}`, async () => this.createSwmTargetExecutorSessionV1()
|
|
5168
5467
|
.recoverPrivateTarget({
|
|
5169
5468
|
remotePeerId,
|
|
5170
5469
|
contextGraphId,
|
|
5171
|
-
includeRootScope: this.
|
|
5470
|
+
includeRootScope: this.rfc64LegacySwmGossipAllowedForContextGraph(contextGraphId)
|
|
5471
|
+
// A private graph's root scope stays on the legacy member lane
|
|
5472
|
+
// while its RFC-64 authority is not active (#2858).
|
|
5473
|
+
|| await this.rfc64PrivateRootSwmOnLegacyLaneV1(contextGraphId),
|
|
5172
5474
|
}), { source: 'swm-recovery' });
|
|
5173
5475
|
}
|
|
5174
5476
|
/**
|
|
@@ -5300,16 +5602,6 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5300
5602
|
});
|
|
5301
5603
|
}
|
|
5302
5604
|
/** Focused VM-recovery operation that returns clean per-peer miss evidence. */
|
|
5303
|
-
async syncVmRecoveryFromConnectedPeers(contextGraphId, options) {
|
|
5304
|
-
const catchup = await this.syncContextGraphFromConnectedPeers(contextGraphId, options);
|
|
5305
|
-
return {
|
|
5306
|
-
catchup,
|
|
5307
|
-
// Embedders may still override the catch-up method with the pre-evidence
|
|
5308
|
-
// result shape. Treat that legacy shape as no proof; production results
|
|
5309
|
-
// always carry the immutable field below.
|
|
5310
|
-
cleanMissPeerIds: [...(catchup.cleanSharedMemoryPeerIds ?? [])],
|
|
5311
|
-
};
|
|
5312
|
-
}
|
|
5313
5605
|
selectCatchupPeerWindow(peers, options) {
|
|
5314
5606
|
const maxPeers = options?.maxPeers;
|
|
5315
5607
|
if (maxPeers === undefined || !Number.isInteger(maxPeers) || maxPeers <= 0) {
|
|
@@ -5470,7 +5762,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5470
5762
|
// into HEAD's `accessDeniedPeers` counter so the existing daemon
|
|
5471
5763
|
// catchup-status endpoint and UI keep working — see
|
|
5472
5764
|
// `cli/src/daemon.ts` subscribe job and `catchup-runner.ts`.
|
|
5473
|
-
const emptyShared = () =>
|
|
5765
|
+
const emptyShared = () => emptySharedMemorySyncResult(1);
|
|
5474
5766
|
// Bounded fan-out: at most CATCHUP_MAX_CONCURRENT_PEER_SYNCS peer syncs run
|
|
5475
5767
|
// at once. The pre-cap unbounded `Promise.all` over every sync-capable peer
|
|
5476
5768
|
// was the top amplifier of the 2026-07-07 mainnet sync storm — one
|
|
@@ -5755,7 +6047,13 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5755
6047
|
const ctx = createOperationContext('sync');
|
|
5756
6048
|
await primeCatchupConnectionsAtom(this.node.libp2p, this.discovery, this.peerId, async (peerId) => {
|
|
5757
6049
|
await this.networkAdmissionCoordinator.ensureAdmitted(peerId, ctx);
|
|
5758
|
-
}
|
|
6050
|
+
},
|
|
6051
|
+
// An on-demand phonebook holds every relay-advertising profile; walking
|
|
6052
|
+
// all of them on each catch-up is a dial storm. Nodes that sync the
|
|
6053
|
+
// phonebook on every connect (and the kill switch) keep today's walk.
|
|
6054
|
+
this.onDemandAgentsPhonebookEnabled()
|
|
6055
|
+
? { maxDials: AGENTS_PHONEBOOK_PRIME_MAX_DIALS }
|
|
6056
|
+
: {});
|
|
5759
6057
|
}
|
|
5760
6058
|
/**
|
|
5761
6059
|
* Pull `_meta` (and SWM) for a CG immediately after receiving a curator
|
|
@@ -5786,26 +6084,16 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5786
6084
|
const ctx = createOperationContext('sync');
|
|
5787
6085
|
const curatorShort = curatorPeerId.slice(-8);
|
|
5788
6086
|
let curatorTargetSucceeded = false;
|
|
5789
|
-
|
|
5790
|
-
|
|
6087
|
+
// One acceptance (member proof plus authenticated policy) judges both the
|
|
6088
|
+
// snapshot the curator serves and the local proof that completes the join.
|
|
6089
|
+
const acceptance = await this.resolveApprovedMemberAcceptance(contextGraphId);
|
|
6090
|
+
if (!acceptance) {
|
|
5791
6091
|
throw new Error(`Post-approval sync for "${contextGraphId}" has no approved local agent binding`);
|
|
5792
6092
|
}
|
|
5793
|
-
let expectedDelegateeOpKey;
|
|
5794
|
-
try {
|
|
5795
|
-
expectedDelegateeOpKey = await inferAdapterPublisherAddress(this.chain);
|
|
5796
|
-
}
|
|
5797
|
-
catch {
|
|
5798
|
-
// The signed join flow always binds the current libp2p peer, so an
|
|
5799
|
-
// adapter that cannot expose its op-key still has a usable proof.
|
|
5800
|
-
}
|
|
5801
6093
|
const curatorMetaRefreshOptions = {
|
|
5802
6094
|
trustedCuratorPeerId: curatorPeerId,
|
|
5803
6095
|
force: true,
|
|
5804
|
-
|
|
5805
|
-
approvedAgentAddress,
|
|
5806
|
-
expectedDelegateePeerId: this.peerId,
|
|
5807
|
-
expectedDelegateeOpKey,
|
|
5808
|
-
},
|
|
6096
|
+
approvedMember: acceptance,
|
|
5809
6097
|
};
|
|
5810
6098
|
// Curator-direct attempt. Any throw here (relay reservation gone,
|
|
5811
6099
|
// dial timeout, AbortSignal, transient `Remote closed connection
|
|
@@ -5849,12 +6137,14 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5849
6137
|
// transfer into a false-ready subscription. Retry once after each
|
|
5850
6138
|
// catchup round and require a live metadata proof before declaring
|
|
5851
6139
|
// the curator-targeted bootstrap complete.
|
|
5852
|
-
|
|
5853
|
-
|
|
6140
|
+
// The bootstrap completes only once the local metadata proves this
|
|
6141
|
+
// approved member; a public definition stored before the join
|
|
6142
|
+
// (RFC-64 bootstrap) must not end it while the curator's snapshot
|
|
6143
|
+
// is still stale (#2831 review).
|
|
6144
|
+
let hasAuthoritativeMeta = await this.hasConfirmedApprovedMemberMetaState(contextGraphId, acceptance).catch(() => false);
|
|
5854
6145
|
if (!hasAuthoritativeMeta) {
|
|
5855
6146
|
await this.refreshMetaFromCurator(contextGraphId, curatorMetaRefreshOptions);
|
|
5856
|
-
hasAuthoritativeMeta = await this.
|
|
5857
|
-
.catch(() => false);
|
|
6147
|
+
hasAuthoritativeMeta = await this.hasConfirmedApprovedMemberMetaState(contextGraphId, acceptance).catch(() => false);
|
|
5858
6148
|
}
|
|
5859
6149
|
if (hasAuthoritativeMeta) {
|
|
5860
6150
|
await this.refreshMetaSyncedFlags([contextGraphId]);
|
|
@@ -5907,53 +6197,94 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
5907
6197
|
* authorize VM, payload, plaintext-recovery, or SWM activation. Those lanes
|
|
5908
6198
|
* are installed only after the fetched metadata (or the registered chain
|
|
5909
6199
|
* roster) makes the ordinary read-authority resolver return `allowed`.
|
|
6200
|
+
*
|
|
6201
|
+
* Reports whether a later attempt can still succeed: a failed fetch, a
|
|
6202
|
+
* snapshot that does not prove this member yet, or unavailable authority is
|
|
6203
|
+
* `retry`; no approval binding or denied authority is `stop`.
|
|
5910
6204
|
*/
|
|
5911
|
-
async resumePendingJoinApprovalMetadata(contextGraphId, curatorPeerId) {
|
|
6205
|
+
async resumePendingJoinApprovalMetadata(contextGraphId, curatorPeerId, curatorDialAddress) {
|
|
5912
6206
|
const ctx = createOperationContext('sync');
|
|
5913
|
-
const
|
|
5914
|
-
if (!
|
|
5915
|
-
return;
|
|
5916
|
-
let expectedDelegateeOpKey;
|
|
5917
|
-
try {
|
|
5918
|
-
expectedDelegateeOpKey = await inferAdapterPublisherAddress(this.chain);
|
|
5919
|
-
}
|
|
5920
|
-
catch {
|
|
5921
|
-
// The durable approval always binds the current libp2p peer. An adapter
|
|
5922
|
-
// without an observable operational key still has a usable proof.
|
|
5923
|
-
}
|
|
6207
|
+
const acceptance = await this.resolveApprovedMemberAcceptance(contextGraphId);
|
|
6208
|
+
if (!acceptance)
|
|
6209
|
+
return 'stop';
|
|
5924
6210
|
const refreshed = await this.refreshMetaFromCurator(contextGraphId, {
|
|
5925
6211
|
trustedCuratorPeerId: curatorPeerId,
|
|
6212
|
+
curatorDialAddressHint: curatorDialAddress,
|
|
5926
6213
|
force: true,
|
|
5927
|
-
|
|
5928
|
-
approvedAgentAddress,
|
|
5929
|
-
expectedDelegateePeerId: this.peerId,
|
|
5930
|
-
expectedDelegateeOpKey,
|
|
5931
|
-
},
|
|
6214
|
+
approvedMember: acceptance,
|
|
5932
6215
|
}).catch((error) => {
|
|
5933
6216
|
this.log.warn(ctx, `Pending join-approval metadata recovery for "${contextGraphId}" failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
5934
6217
|
return false;
|
|
5935
6218
|
});
|
|
5936
|
-
if (!refreshed
|
|
6219
|
+
if (!refreshed
|
|
6220
|
+
|| !(await this.hasConfirmedApprovedMemberMetaState(contextGraphId, acceptance)
|
|
6221
|
+
.catch(() => false))) {
|
|
5937
6222
|
this.log.warn(ctx, `Pending join-approval metadata recovery for "${contextGraphId}" did not establish authoritative metadata; keeping data lanes closed`);
|
|
5938
|
-
return;
|
|
6223
|
+
return 'retry';
|
|
5939
6224
|
}
|
|
5940
6225
|
const authority = await withRpcUsageSite(CG_AUTH_RPC_SITES.joinResume, () => this.resolveContextGraphReadAuthority(contextGraphId, {
|
|
5941
6226
|
allowSubscriptionFallback: false,
|
|
5942
6227
|
})).catch(() => ({ outcome: 'unavailable' }));
|
|
5943
6228
|
if (authority.outcome !== 'allowed') {
|
|
5944
6229
|
this.log.warn(ctx, `Pending join-approval metadata recovery for "${contextGraphId}" completed but current read authority is ${authority.outcome}; keeping data lanes closed`);
|
|
5945
|
-
|
|
5946
|
-
|
|
6230
|
+
// A stale approval cannot override an explicit current denial.
|
|
6231
|
+
return authority.outcome === 'unavailable' ? 'retry' : 'stop';
|
|
6232
|
+
}
|
|
6233
|
+
// A shutdown that began during the reads above must not clear the row's
|
|
6234
|
+
// pending state or open its data lanes while the node tears down; the
|
|
6235
|
+
// next start recovers the row again.
|
|
6236
|
+
const stopping = () => this.node.stopSignal?.aborted === true;
|
|
6237
|
+
if (stopping())
|
|
6238
|
+
return 'stop';
|
|
5947
6239
|
await this.refreshMetaSyncedFlags([contextGraphId]);
|
|
5948
6240
|
const current = this.subscribedContextGraphs.get(contextGraphId);
|
|
5949
|
-
if (!current?.subscribed)
|
|
5950
|
-
return;
|
|
6241
|
+
if (!current?.subscribed || stopping())
|
|
6242
|
+
return 'stop';
|
|
5951
6243
|
this.subscribeToContextGraph(contextGraphId, {
|
|
5952
6244
|
persist: false,
|
|
5953
6245
|
syncMode: current.syncMode,
|
|
5954
6246
|
});
|
|
5955
6247
|
this.persistLocalNodeMembership(contextGraphId, 'rehydrated-subscription');
|
|
5956
6248
|
await this.runImmediatePostApprovalSync(contextGraphId, curatorPeerId);
|
|
6249
|
+
return 'completed';
|
|
6250
|
+
}
|
|
6251
|
+
/**
|
|
6252
|
+
* Run the restricted pending-metadata recovery of a restarted join approval
|
|
6253
|
+
* until it completes or can no longer complete (#2832). Right after a
|
|
6254
|
+
* restart the node's authority reads can still be rebuilding its finalized
|
|
6255
|
+
* index, so a single attempt could fail transiently and leave every data
|
|
6256
|
+
* lane closed until the next restart. A `retry` outcome, or an attempt that
|
|
6257
|
+
* throws, is tried again with backoff while the row is still a subscribed,
|
|
6258
|
+
* join-approved, pending-metadata row; the node stopping ends the loop.
|
|
6259
|
+
*/
|
|
6260
|
+
async recoverPendingJoinApprovalMetadata(contextGraphId, curatorPeerId, curatorDialAddress) {
|
|
6261
|
+
const stopSignal = this.node.stopSignal;
|
|
6262
|
+
for (let attempt = 0;; attempt += 1) {
|
|
6263
|
+
let outcome;
|
|
6264
|
+
try {
|
|
6265
|
+
outcome = await this.resumePendingJoinApprovalMetadata(contextGraphId, curatorPeerId, curatorDialAddress);
|
|
6266
|
+
}
|
|
6267
|
+
catch (error) {
|
|
6268
|
+
// A store or network fault that escapes an attempt is as transient as
|
|
6269
|
+
// a `retry`. Ending the loop on it would leave the row closed until
|
|
6270
|
+
// the next restart again.
|
|
6271
|
+
this.log.warn(createOperationContext('sync'), `Pending join-approval recovery attempt for "${contextGraphId}" failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
6272
|
+
outcome = 'retry';
|
|
6273
|
+
}
|
|
6274
|
+
if (outcome !== 'retry')
|
|
6275
|
+
return;
|
|
6276
|
+
const delayMs = JOIN_APPROVAL_METADATA_RECOVERY_RETRY_MS[Math.min(attempt, JOIN_APPROVAL_METADATA_RECOVERY_RETRY_MS.length - 1)];
|
|
6277
|
+
if (!(await waitUnlessStopped(delayMs, stopSignal)))
|
|
6278
|
+
return;
|
|
6279
|
+
const current = this.subscribedContextGraphs.get(contextGraphId);
|
|
6280
|
+
if (!this.localApprovedAgentByCG.has(contextGraphId)
|
|
6281
|
+
|| current?.subscribed !== true
|
|
6282
|
+
// A concurrent data catch-up can set `synced` while authoritative
|
|
6283
|
+
// join metadata is still pending or unknown. Only its explicit
|
|
6284
|
+
// confirmation ends this join-specific retry.
|
|
6285
|
+
|| (current.synced === true && current.metaSynced === true && current.pendingMeta !== true))
|
|
6286
|
+
return;
|
|
6287
|
+
}
|
|
5957
6288
|
}
|
|
5958
6289
|
selectCatchupPeers(peers, preferredPeerId, privateOnly = false) {
|
|
5959
6290
|
return orderCatchupPeers(peers, preferredPeerId, privateOnly, this.peerCapabilityRegistry.snapshotCorePeerIds());
|
|
@@ -6008,7 +6339,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6008
6339
|
* abort contract.
|
|
6009
6340
|
*/
|
|
6010
6341
|
async waitForSyncProtocol(pid, signal) {
|
|
6011
|
-
return waitForPeerProtocol(this.node.libp2p.peerStore, pid,
|
|
6342
|
+
return waitForPeerProtocol(this.node.libp2p.peerStore, pid,
|
|
6343
|
+
// Either id proves sync support (#2822; see `advertisesSyncProtocol`).
|
|
6344
|
+
[PROTOCOL_SYNC, PROTOCOL_SYNC_POOLED], SYNC_PROTOCOL_CHECK_ATTEMPTS, SYNC_PROTOCOL_CHECK_DELAY_MS, signal);
|
|
6012
6345
|
}
|
|
6013
6346
|
async refreshMetaSyncedFlags(contextGraphIds) {
|
|
6014
6347
|
for (const contextGraphId of contextGraphIds) {
|
|
@@ -6327,14 +6660,16 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6327
6660
|
pending.add(revision);
|
|
6328
6661
|
}
|
|
6329
6662
|
enqueueContextGraphSubscriptionPersistWrite(contextGraphId, write) {
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6663
|
+
// The scheduler owns per-context-graph ordering, strict non-coalescing,
|
|
6664
|
+
// write-start timing (a microtask after admission), shutdown drain and
|
|
6665
|
+
// bounds; the revision maps below stay the cancel/supersede layer on top of
|
|
6666
|
+
// it. The returned promise rejects when the write (or admission) fails, so
|
|
6667
|
+
// an awaiting caller sees the failure. The lane keeps draining, so a failed
|
|
6668
|
+
// write does not stall the next one for this context graph.
|
|
6669
|
+
const run = this.contextGraphSubscriptionPersistence.enqueue(contextGraphId, write);
|
|
6670
|
+
// Idle cleanup runs after the caller's own handlers and marks a failure as
|
|
6671
|
+
// handled for a caller that drops the promise, as the chain tail did.
|
|
6672
|
+
void run.catch(() => undefined).finally(() => {
|
|
6338
6673
|
this.clearContextGraphSubscriptionPersistRevisionStateIfIdle(contextGraphId);
|
|
6339
6674
|
});
|
|
6340
6675
|
return run;
|
|
@@ -6355,7 +6690,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6355
6690
|
clearContextGraphSubscriptionPersistRevisionStateIfIdle(contextGraphId) {
|
|
6356
6691
|
if ((this.contextGraphSubscriptionPersistPendingRevisions.get(contextGraphId)?.size ?? 0) > 0)
|
|
6357
6692
|
return;
|
|
6358
|
-
if (this.
|
|
6693
|
+
if (this.contextGraphSubscriptionPersistence.hasLane(contextGraphId))
|
|
6359
6694
|
return;
|
|
6360
6695
|
const sub = this.subscribedContextGraphs.get(contextGraphId);
|
|
6361
6696
|
if (sub?.subscribed === true || sub?.coreHosted === true)
|
|
@@ -6506,6 +6841,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6506
6841
|
const recoverySelectionChanged = effects.recoveryChanged;
|
|
6507
6842
|
if (!receiverSelectionChanged && !recoverySelectionChanged)
|
|
6508
6843
|
return;
|
|
6844
|
+
// Record the inactive edge synchronously: a same-tick resubscription can
|
|
6845
|
+
// otherwise look like an unchanged active lane to repair backoff.
|
|
6846
|
+
this.observeRfc64SwmCatalogProjectionLaneAvailabilityV1(contextGraphId);
|
|
6509
6847
|
if (receiverSelectionChanged && !effects.nextReceiverActive) {
|
|
6510
6848
|
this.rfc64PublicCatalogServiceV1?.deactivateReceiverContextGraph(contextGraphId);
|
|
6511
6849
|
this.clearRfc64CatalogOperationalTargetsV1(contextGraphId);
|
|
@@ -6539,8 +6877,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6539
6877
|
void this.replayRfc64CatalogToConnectedPeersV1(contextGraphId)
|
|
6540
6878
|
.catch(() => undefined);
|
|
6541
6879
|
}
|
|
6542
|
-
//
|
|
6543
|
-
//
|
|
6880
|
+
// The observed inactive edge makes this recovery eligible immediately,
|
|
6881
|
+
// including retryIntervalMs=0; duplicate active starts retain cooldown.
|
|
6544
6882
|
this.startRfc64SwmCatalogProjectionSupervisorV1(createOperationContext('system'));
|
|
6545
6883
|
}
|
|
6546
6884
|
}
|
|
@@ -6650,6 +6988,12 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6650
6988
|
this.finishContextGraphSubscriptionPersistRevision(contextGraphId, options?.revision);
|
|
6651
6989
|
});
|
|
6652
6990
|
}
|
|
6991
|
+
/**
|
|
6992
|
+
* Strict write of a row that must be durable. Throws when the projection
|
|
6993
|
+
* would keep member intent process-local, so it suits persisted-row
|
|
6994
|
+
* activation, not the sync path of a live on-demand subscription (see
|
|
6995
|
+
* {@link persistContextGraphSyncStateStrict}).
|
|
6996
|
+
*/
|
|
6653
6997
|
async persistContextGraphSubscriptionStrict(contextGraphId, subscription, syncScoped, isCurrent = () => true) {
|
|
6654
6998
|
await this.persistContextGraphSubscriptionProjectionStrict({
|
|
6655
6999
|
contextGraphId,
|
|
@@ -6661,10 +7005,11 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6661
7005
|
});
|
|
6662
7006
|
}
|
|
6663
7007
|
/**
|
|
6664
|
-
* One strict subscription persistence protocol shared by joins
|
|
6665
|
-
* discovery. It owns snapshot
|
|
6666
|
-
*
|
|
6667
|
-
*
|
|
7008
|
+
* One strict subscription persistence protocol shared by joins, registry
|
|
7009
|
+
* discovery, and sync-owned binding and cursor progress. It owns snapshot
|
|
7010
|
+
* capture, generation validation, per-graph serialization, and the
|
|
7011
|
+
* store-first write. Callers select only whether an intentionally
|
|
7012
|
+
* process-local on-demand member projection is acceptable.
|
|
6668
7013
|
*/
|
|
6669
7014
|
async persistContextGraphSubscriptionProjectionStrict(input) {
|
|
6670
7015
|
const store = this.config.contextGraphSubscriptionStore;
|
|
@@ -6678,7 +7023,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6678
7023
|
const expectedBindingGeneration = this.contextGraphBindingState.capture(input.contextGraphId);
|
|
6679
7024
|
const sub = input.subscription ?? expectedLiveSub;
|
|
6680
7025
|
if (!sub?.subscribed && !sub?.coreHosted) {
|
|
6681
|
-
throw new Error(`Cannot persist context graph "${input.contextGraphId}": active subscription or host state is missing`);
|
|
7026
|
+
throw new Error(`Cannot persist context graph "${input.contextGraphId}" (${input.operation}): active subscription or host state is missing`);
|
|
6682
7027
|
}
|
|
6683
7028
|
const persistence = projectContextGraphSubscriptionPersistence({
|
|
6684
7029
|
contextGraphId: input.contextGraphId,
|
|
@@ -6702,7 +7047,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6702
7047
|
|| current !== expectedLiveSub
|
|
6703
7048
|
|| (!current?.subscribed && !current?.coreHosted)
|
|
6704
7049
|
|| !this.contextGraphBindingState.isGenerationCurrent(input.contextGraphId, expectedBindingGeneration)) {
|
|
6705
|
-
throw asSyncFetchAbortError(new Error(`Context graph "${input.contextGraphId}" changed before its strict subscription snapshot was persisted`));
|
|
7050
|
+
throw asSyncFetchAbortError(new Error(`Context graph "${input.contextGraphId}" changed before its strict subscription snapshot (${input.operation}) was persisted`));
|
|
6706
7051
|
}
|
|
6707
7052
|
await store.save(record);
|
|
6708
7053
|
});
|
|
@@ -6722,6 +7067,25 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6722
7067
|
operation: 'chain discovery',
|
|
6723
7068
|
});
|
|
6724
7069
|
}
|
|
7070
|
+
/**
|
|
7071
|
+
* Sync-owned durability boundary for a live subscription's on-chain id
|
|
7072
|
+
* binding and VM reconcile cursor. Like chain discovery, sync keeps the
|
|
7073
|
+
* canonical projection instead of demanding durable member intent: an
|
|
7074
|
+
* on-demand member subscription is process-local, so nothing is written and
|
|
7075
|
+
* the caller advances only its in-memory state; a Core hosting obligation
|
|
7076
|
+
* still saves its host-only row; an always-on subscription is saved before
|
|
7077
|
+
* the caller exposes the new state. Demanding member intent here stalled
|
|
7078
|
+
* every `dkg subscribe` without `--save` at its first cursor advance.
|
|
7079
|
+
*/
|
|
7080
|
+
async persistContextGraphSyncStateStrict(contextGraphId, subscription, operation, isCurrent) {
|
|
7081
|
+
await this.persistContextGraphSubscriptionProjectionStrict({
|
|
7082
|
+
contextGraphId,
|
|
7083
|
+
subscription,
|
|
7084
|
+
isCurrent,
|
|
7085
|
+
requireDurableMemberIntent: false,
|
|
7086
|
+
operation,
|
|
7087
|
+
});
|
|
7088
|
+
}
|
|
6725
7089
|
/**
|
|
6726
7090
|
* Persist the two durable halves of a requester-side join approval.
|
|
6727
7091
|
*
|
|
@@ -7005,12 +7369,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7005
7369
|
onChainId: row.onChainId,
|
|
7006
7370
|
onChainHash: row.onChainHash,
|
|
7007
7371
|
},
|
|
7008
|
-
}).catch(() => (
|
|
7009
|
-
outcome: 'unavailable',
|
|
7010
|
-
source: 'legacy-local',
|
|
7011
|
-
reason: 'unexpected-authority-error',
|
|
7012
|
-
metadataBootstrap: 'eligible',
|
|
7013
|
-
}))),
|
|
7372
|
+
}).catch((error) => unavailableContextGraphReadAuthorityDecision('legacy-local', 'unexpected-authority-error', contextGraphReadAuthorityDependencyOf(error)))),
|
|
7014
7373
|
activate: async (row, onChainId, revision) => {
|
|
7015
7374
|
await this.activatePersistedContextGraphSubscriptionRecord(row, {
|
|
7016
7375
|
onChainId,
|
|
@@ -7048,6 +7407,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7048
7407
|
});
|
|
7049
7408
|
this.log.info(ctx, `Activated persisted context-graph subscription "${contextGraphId}" after authority recovery`);
|
|
7050
7409
|
},
|
|
7410
|
+
capped: (contextGraphId) => {
|
|
7411
|
+
this.contextGraphSubscriptionRehydrationPendingIds.add(contextGraphId);
|
|
7412
|
+
this.contextGraphSubscriptionRehydrationPromotionRuntime?.request();
|
|
7413
|
+
},
|
|
7051
7414
|
});
|
|
7052
7415
|
}
|
|
7053
7416
|
/**
|
|
@@ -7130,12 +7493,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7130
7493
|
onChainId: row.onChainId,
|
|
7131
7494
|
onChainHash: row.onChainHash,
|
|
7132
7495
|
},
|
|
7133
|
-
}).catch(() => (
|
|
7134
|
-
outcome: 'unavailable',
|
|
7135
|
-
source: 'legacy-local',
|
|
7136
|
-
reason: 'unexpected-authority-error',
|
|
7137
|
-
metadataBootstrap: 'eligible',
|
|
7138
|
-
}));
|
|
7496
|
+
}).catch((error) => unavailableContextGraphReadAuthorityDecision('legacy-local', 'unexpected-authority-error', contextGraphReadAuthorityDependencyOf(error)));
|
|
7139
7497
|
signal.throwIfAborted();
|
|
7140
7498
|
if (!runtime.owns(signal))
|
|
7141
7499
|
return 'idle';
|
|
@@ -7298,6 +7656,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7298
7656
|
if (!store)
|
|
7299
7657
|
return;
|
|
7300
7658
|
const ctx = createOperationContext('init');
|
|
7659
|
+
let authorityBudget;
|
|
7660
|
+
const startupPlan = this.gossipSession.beginDurableStartupPlan(this.contextGraphSubscriptionRehydrationAccountedIds);
|
|
7301
7661
|
try {
|
|
7302
7662
|
// System context graphs (AGENTS/ONTOLOGY) are auto-subscribed separately
|
|
7303
7663
|
// by start(); their persisted rows must NOT be rehydrated here too. Re-
|
|
@@ -7306,6 +7666,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7306
7666
|
// dormant. Exclude them from the rehydration set entirely.
|
|
7307
7667
|
const systemContextGraphs = new Set(Object.values(SYSTEM_CONTEXT_GRAPHS));
|
|
7308
7668
|
const persistedRows = await store.loadAll();
|
|
7669
|
+
startupPlan.claimDurableRows(persistedRows);
|
|
7309
7670
|
// A name-hash placeholder whose verified cleartext row is also durable
|
|
7310
7671
|
// was adopted earlier; the crash window between the two writes can
|
|
7311
7672
|
// leave both. Never reactivate the placeholder. Record the adoption as
|
|
@@ -7381,10 +7742,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7381
7742
|
// snapshot already read by the provenance phase. Load every persisted
|
|
7382
7743
|
// row (not just rows under the activation cap) so a dormant subscription
|
|
7383
7744
|
// still has the right signer when an operator activates it explicitly.
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7745
|
+
const newestApprovalByContextGraph = persistedMembershipRows === null
|
|
7746
|
+
? null
|
|
7747
|
+
: projectPersistedJoinApprovals(persistedMembershipRows, new Set(rows.map((row) => row.id)), new Set([...this.localAgents.keys()].map((address) => address.toLowerCase())));
|
|
7748
|
+
if (newestApprovalByContextGraph) {
|
|
7388
7749
|
for (const [contextGraphId, approval] of newestApprovalByContextGraph) {
|
|
7389
7750
|
this.localApprovedAgentByCG.set(contextGraphId, approval.principalId);
|
|
7390
7751
|
if (approval.curatorPeerId) {
|
|
@@ -7419,6 +7780,43 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7419
7780
|
dormancyById.clear();
|
|
7420
7781
|
const activatedRows = [];
|
|
7421
7782
|
let activatedUserRows = 0;
|
|
7783
|
+
// #2815: every row's authority may need a chain read, and start() (with
|
|
7784
|
+
// the daemon API behind it) waits for this loop. Past the budget, a row
|
|
7785
|
+
// without a durable join approval is left dormant as
|
|
7786
|
+
// `authorityUnavailable` unread; background authority recovery resolves
|
|
7787
|
+
// it after start and activates it only once it resolves as allowed.
|
|
7788
|
+
const configuredAuthorityBudgetMs = this.config.contextGraphSubscriptionRehydrationAuthorityBudgetMs;
|
|
7789
|
+
let authorityBudgetMs = DEFAULT_REHYDRATION_STARTUP_AUTHORITY_BUDGET_MS;
|
|
7790
|
+
if (configuredAuthorityBudgetMs != null) {
|
|
7791
|
+
if (Number.isSafeInteger(configuredAuthorityBudgetMs)
|
|
7792
|
+
&& configuredAuthorityBudgetMs >= 0
|
|
7793
|
+
&& configuredAuthorityBudgetMs <= MAX_REHYDRATION_AUTHORITY_BUDGET_MS) {
|
|
7794
|
+
authorityBudgetMs = configuredAuthorityBudgetMs;
|
|
7795
|
+
}
|
|
7796
|
+
else {
|
|
7797
|
+
this.log.warn(ctx, `Ignoring invalid contextGraphSubscriptionRehydrationAuthorityBudgetMs=${configuredAuthorityBudgetMs} ` +
|
|
7798
|
+
`(must be a whole number of milliseconds from 0 to ${MAX_REHYDRATION_AUTHORITY_BUDGET_MS}); ` +
|
|
7799
|
+
`using default ${DEFAULT_REHYDRATION_STARTUP_AUTHORITY_BUDGET_MS}.`);
|
|
7800
|
+
}
|
|
7801
|
+
}
|
|
7802
|
+
const deferredIds = [];
|
|
7803
|
+
let deferredUserRows = 0;
|
|
7804
|
+
// Past the budget, a user row goes to background authority recovery only
|
|
7805
|
+
// while the activation cap still has room for it; beyond that it waits
|
|
7806
|
+
// for rolling activation unread, as a row beyond the cap always has.
|
|
7807
|
+
// Hosted rows are exempt from the cap and always go to recovery.
|
|
7808
|
+
const leaveUnresolved = (row) => {
|
|
7809
|
+
if (!row.coreHosted && cap > 0 && activatedUserRows + deferredUserRows >= cap) {
|
|
7810
|
+
dormancyById.set(row.id, 'activationCap');
|
|
7811
|
+
this.contextGraphSubscriptionRehydrationPendingIds.add(row.id);
|
|
7812
|
+
return;
|
|
7813
|
+
}
|
|
7814
|
+
if (!row.coreHosted)
|
|
7815
|
+
deferredUserRows += 1;
|
|
7816
|
+
dormancyById.set(row.id, 'authorityUnavailable');
|
|
7817
|
+
deferredIds.push(row.id);
|
|
7818
|
+
};
|
|
7819
|
+
authorityBudget = startRehydrationAuthorityBudget(authorityBudgetMs);
|
|
7422
7820
|
for (let i = 0; i < toActivate.length; i++) {
|
|
7423
7821
|
const row = toActivate[i];
|
|
7424
7822
|
// The cap limits successful non-hosted activations, not candidates.
|
|
@@ -7434,7 +7832,29 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7434
7832
|
const approvedAgentAddress = row.subscribed
|
|
7435
7833
|
? this.localApprovedAgentByCG.get(row.id)
|
|
7436
7834
|
: undefined;
|
|
7437
|
-
|
|
7835
|
+
let hasJoinApproval = approvedAgentAddress !== undefined;
|
|
7836
|
+
// The membership row is the restart hint, not the current requester
|
|
7837
|
+
// decision. A later explicit pending/rejected decision must retire a
|
|
7838
|
+
// stale join-approved hint instead of resurrecting its subscription in
|
|
7839
|
+
// restricted pending-metadata mode. Missing decision state remains the
|
|
7840
|
+
// compatibility shape for legacy persisted membership rows.
|
|
7841
|
+
if (approvedAgentAddress !== undefined) {
|
|
7842
|
+
try {
|
|
7843
|
+
const requesterState = await this.readRequesterJoinRequestState(row.id, approvedAgentAddress);
|
|
7844
|
+
hasJoinApproval = requesterState === null
|
|
7845
|
+
|| requesterState.status === 'approved';
|
|
7846
|
+
}
|
|
7847
|
+
catch {
|
|
7848
|
+
hasJoinApproval = false;
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
// A join-approved row keeps the synchronous path: only it can restore
|
|
7852
|
+
// the restricted pending-metadata bootstrap, which background
|
|
7853
|
+
// authority recovery does not offer.
|
|
7854
|
+
if (!hasJoinApproval && authorityBudget.spent()) {
|
|
7855
|
+
leaveUnresolved(row);
|
|
7856
|
+
continue;
|
|
7857
|
+
}
|
|
7438
7858
|
// A crash between a historical false-ready sync and the approval
|
|
7439
7859
|
// reset could leave all three persisted bits true. The durable
|
|
7440
7860
|
// join-approved marker identifies a private bootstrap, so prove both
|
|
@@ -7458,7 +7878,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7458
7878
|
// in-memory state needed for one authenticated metadata fetch. That
|
|
7459
7879
|
// restricted path cannot activate data lanes until this same authority
|
|
7460
7880
|
// resolver subsequently returns `allowed`.
|
|
7461
|
-
const
|
|
7881
|
+
const authorityRead = this.resolveContextGraphSubscriptionBootstrapAuthority(row.id, {
|
|
7462
7882
|
allowSubscriptionFallback: false,
|
|
7463
7883
|
signal: AbortSignal.timeout(chainAuthorityReadBudgetsOf(this).requestTimeoutMs),
|
|
7464
7884
|
durableSubscriptionBinding: {
|
|
@@ -7466,12 +7886,16 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7466
7886
|
onChainId: row.onChainId,
|
|
7467
7887
|
onChainHash: row.onChainHash,
|
|
7468
7888
|
},
|
|
7469
|
-
}).catch(() => (
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7889
|
+
}).catch((error) => unavailableContextGraphReadAuthorityDecision('legacy-local', 'unexpected-authority-error', contextGraphReadAuthorityDependencyOf(error)));
|
|
7890
|
+
// A read the budget stops waiting for ends on its own request
|
|
7891
|
+
// timeout; its late answer is ignored and activates nothing.
|
|
7892
|
+
const readAuthority = hasJoinApproval
|
|
7893
|
+
? await authorityRead
|
|
7894
|
+
: await authorityBudget.race(authorityRead);
|
|
7895
|
+
if (readAuthority === REHYDRATION_AUTHORITY_DEFERRED) {
|
|
7896
|
+
leaveUnresolved(row);
|
|
7897
|
+
continue;
|
|
7898
|
+
}
|
|
7475
7899
|
// A stale approval cannot override an explicit current membership
|
|
7476
7900
|
// denial. The authority resolver supplies a typed bootstrap policy so
|
|
7477
7901
|
// lifecycle code never infers security semantics from diagnostic text.
|
|
@@ -7519,7 +7943,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7519
7943
|
const curatorPeerId = this.preferredSyncPeers.get(row.id);
|
|
7520
7944
|
this.log.info(ctx, `Restored persisted context-graph subscription "${row.id}" in restricted pending-metadata mode; VM, payload recovery, and SWM remain closed`);
|
|
7521
7945
|
if (curatorPeerId) {
|
|
7522
|
-
void this.
|
|
7946
|
+
void this.recoverPendingJoinApprovalMetadata(row.id, curatorPeerId, newestApprovalByContextGraph?.get(row.id)?.curatorDialAddress).catch((error) => {
|
|
7523
7947
|
this.log.warn(ctx, `Pending join-approval recovery for "${row.id}" stopped safely: ${error instanceof Error ? error.message : String(error)}`);
|
|
7524
7948
|
});
|
|
7525
7949
|
}
|
|
@@ -7579,13 +8003,23 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7579
8003
|
if (dormancy.dormantReasons.authorityDenied.length > 0) {
|
|
7580
8004
|
this.log.warn(ctx, `${dormancy.dormantReasons.authorityDenied.length} context-graph subscription(s) left dormant because current read authority denied this node.`);
|
|
7581
8005
|
}
|
|
7582
|
-
|
|
7583
|
-
|
|
8006
|
+
const unavailableAtStartup = dormancy.dormantReasons.authorityUnavailable.length - deferredIds.length;
|
|
8007
|
+
if (unavailableAtStartup > 0) {
|
|
8008
|
+
this.log.warn(ctx, `${unavailableAtStartup} context-graph subscription(s) left dormant because current read authority was unavailable; retry after restoring the authority source.`);
|
|
8009
|
+
}
|
|
8010
|
+
if (deferredIds.length > 0) {
|
|
8011
|
+
this.log.warn(ctx, `Stopped waiting on read authority for ${deferredIds.length} persisted context-graph subscription(s) ` +
|
|
8012
|
+
`after the ${authorityBudgetMs} ms startup budget. They stay dormant until background authority ` +
|
|
8013
|
+
`recovery resolves them as allowed.`);
|
|
7584
8014
|
}
|
|
7585
8015
|
}
|
|
7586
8016
|
catch (err) {
|
|
7587
8017
|
this.log.warn(ctx, `Failed to rehydrate persisted context-graph subscriptions: ${err instanceof Error ? err.message : String(err)}`);
|
|
7588
8018
|
}
|
|
8019
|
+
finally {
|
|
8020
|
+
authorityBudget?.dispose();
|
|
8021
|
+
startupPlan.finish();
|
|
8022
|
+
}
|
|
7589
8023
|
}
|
|
7590
8024
|
/**
|
|
7591
8025
|
* Operator recovery for #997: tear down every active in-memory subscription
|
|
@@ -7642,7 +8076,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7642
8076
|
}
|
|
7643
8077
|
}
|
|
7644
8078
|
const activeUserIdsWithPendingStoreWrite = store
|
|
7645
|
-
? activeUserIds.filter((id) => this.
|
|
8079
|
+
? activeUserIds.filter((id) => this.contextGraphSubscriptionPersistence.hasLane(id))
|
|
7646
8080
|
: [];
|
|
7647
8081
|
const storeDeleteIds = [...new Set([...persistedUserIds, ...activeUserIdsWithPendingStoreWrite])];
|
|
7648
8082
|
const total = storeDeleteIds.length;
|
|
@@ -7726,10 +8160,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7726
8160
|
}, normalizedContextGraphId, input),
|
|
7727
8161
|
}, contextGraphId);
|
|
7728
8162
|
}
|
|
7729
|
-
async hasConfirmedMetaState(contextGraphId, options) {
|
|
8163
|
+
async hasConfirmedMetaState(contextGraphId, options = {}) {
|
|
7730
8164
|
return confirmContextGraphMetadataV1({
|
|
7731
8165
|
chain: this.chain,
|
|
7732
|
-
resolveActivePublicChainProof: () => this.resolveActivePublicContextGraphChainProof(contextGraphId, createOperationContext('sync'), options
|
|
8166
|
+
resolveActivePublicChainProof: () => this.resolveActivePublicContextGraphChainProof(contextGraphId, createOperationContext('sync'), options.signal),
|
|
7733
8167
|
isPrivateContextGraph: (id) => this.isPrivateContextGraph(id),
|
|
7734
8168
|
localApprovedAgentByContextGraph: this.localApprovedAgentByCG,
|
|
7735
8169
|
peerId: this.peerId,
|
|
@@ -7737,6 +8171,46 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7737
8171
|
subscriptions: this.subscribedContextGraphs,
|
|
7738
8172
|
}, contextGraphId, options);
|
|
7739
8173
|
}
|
|
8174
|
+
/**
|
|
8175
|
+
* Join bootstrap completion: the local metadata proves this node's approved
|
|
8176
|
+
* member, judged with the same acceptance the snapshot refresh used.
|
|
8177
|
+
*/
|
|
8178
|
+
hasConfirmedApprovedMemberMetaState(contextGraphId, acceptance) {
|
|
8179
|
+
return this.hasConfirmedMetaState(contextGraphId, { purpose: 'approved-member', acceptance });
|
|
8180
|
+
}
|
|
8181
|
+
/**
|
|
8182
|
+
* The one approved-member acceptance a join attempt is judged with: this
|
|
8183
|
+
* node's approval binding, its libp2p peer and operational key, and the
|
|
8184
|
+
* authenticated access policy (#2831 review). The curator refresh and join
|
|
8185
|
+
* completion both consume this same value. `undefined` without an approval
|
|
8186
|
+
* binding.
|
|
8187
|
+
*
|
|
8188
|
+
* The policy is `public` only when the graph's SWM transport authority is
|
|
8189
|
+
* plaintext: registered public, or unregistered under an active accepted
|
|
8190
|
+
* owner-signed public policy (see classifySwmTransportAuthority). A retained
|
|
8191
|
+
* snapshot therefore never outvotes a registration the index shows. Private,
|
|
8192
|
+
* approved-private-replica, legacy-unregistered or unavailable authority, or
|
|
8193
|
+
* an unreadable chain, is `unproven`, which admits only the complete private
|
|
8194
|
+
* definition.
|
|
8195
|
+
*/
|
|
8196
|
+
async resolveApprovedMemberAcceptance(contextGraphId) {
|
|
8197
|
+
const approvedAgentAddress = this.localApprovedAgentByCG.get(contextGraphId);
|
|
8198
|
+
if (!approvedAgentAddress)
|
|
8199
|
+
return undefined;
|
|
8200
|
+
let expectedDelegateeOpKey;
|
|
8201
|
+
try {
|
|
8202
|
+
expectedDelegateeOpKey = await inferAdapterPublisherAddress(this.chain);
|
|
8203
|
+
}
|
|
8204
|
+
catch {
|
|
8205
|
+
// The signed join flow always binds the current libp2p peer, so an
|
|
8206
|
+
// adapter that cannot expose its op-key still has a usable proof.
|
|
8207
|
+
}
|
|
8208
|
+
return resolveApprovedMemberAcceptanceDecision({
|
|
8209
|
+
approvedAgentAddress,
|
|
8210
|
+
expectedDelegateePeerId: this.peerId,
|
|
8211
|
+
expectedDelegateeOpKey,
|
|
8212
|
+
}, () => this.resolveSwmTransportAuthority(contextGraphId, { authorityReadMode: 'finalized-index-or-live' }));
|
|
8213
|
+
}
|
|
7740
8214
|
async hasConfirmedSharedMemoryMetaState(contextGraphId) {
|
|
7741
8215
|
return this.hasConfirmedMetaState(contextGraphId);
|
|
7742
8216
|
}
|
|
@@ -7745,8 +8219,13 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7745
8219
|
// The accepted snapshot is itself finalized, name-bound authority for a
|
|
7746
8220
|
// catalog-owned graph. It replaces both the legacy registration read and
|
|
7747
8221
|
// its metadata-bootstrap proof at this internal transport boundary.
|
|
7748
|
-
if (acceptedRfc64Authority
|
|
7749
|
-
return
|
|
8222
|
+
if (acceptedRfc64Authority === true)
|
|
8223
|
+
return true;
|
|
8224
|
+
// A private graph whose RFC-64 authority is not active keeps the legacy
|
|
8225
|
+
// member checks below (#2858); a refusal by an active authority stands.
|
|
8226
|
+
if (acceptedRfc64Authority === false
|
|
8227
|
+
&& !(await this.rfc64PrivateRootSwmOnLegacyLaneV1(contextGraphId)))
|
|
8228
|
+
return false;
|
|
7750
8229
|
if (!(await this.hasConfirmedSharedMemoryMetaState(contextGraphId))) {
|
|
7751
8230
|
return false;
|
|
7752
8231
|
}
|