keri-ts 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/esm/keri/npm/src/acdc/authoring.js +195 -0
- package/esm/keri/npm/src/acdc/chaining.js +223 -89
- package/esm/keri/npm/src/acdc/custody.js +164 -0
- package/esm/keri/npm/src/acdc/dhking.js +244 -32
- package/esm/keri/npm/src/acdc/observing.js +2 -2
- package/esm/keri/npm/src/acdc/regbasing.js +30 -29
- package/esm/keri/npm/src/acdc/regengine.js +4 -6
- package/esm/keri/npm/src/acdc/registering.js +13 -10
- package/esm/keri/npm/src/acdc/registraring.js +4 -9
- package/esm/keri/npm/src/acdc/salting.js +143 -26
- package/esm/keri/npm/src/acdc/scheming.js +93 -54
- package/esm/keri/npm/src/acdc/unblinding.js +120 -99
- package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
- package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +5 -7
- package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
- package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
- package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
- package/esm/keri/npm/src/app/credentials/root-replicating.js +131 -0
- package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
- package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
- package/esm/keri/npm/src/app/credentials/verifying.js +12 -3
- package/esm/keri/npm/src/app/delivery/forwarding.js +64 -9
- package/esm/keri/npm/src/app/exchanges/exchanging.js +24 -15
- package/esm/keri/npm/src/app/identity/challenging.js +50 -0
- package/esm/keri/npm/src/app/identity/configing.js +17 -43
- package/esm/keri/npm/src/app/identity/delegating.js +77 -77
- package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
- package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
- package/esm/keri/npm/src/app/identity/habbing.js +183 -41
- package/esm/keri/npm/src/app/identity/keeping.js +78 -5
- package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
- package/esm/keri/npm/src/app/ipex/group-ipex.js +327 -0
- package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -0
- package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
- package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
- package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
- package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
- package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +42 -16
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
- package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
- package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
- package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
- package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
- package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
- package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
- package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
- package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
- package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +15 -14
- package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +32 -0
- package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +101 -141
- package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
- package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
- package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
- package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
- package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +44 -6
- package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +113 -65
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
- package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
- package/esm/keri/npm/src/app/runtime/doing.js +17 -0
- package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
- package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
- package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
- package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
- package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
- package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
- package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
- package/esm/keri/npm/src/app/transport/http-client.js +25 -6
- package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
- package/esm/keri/npm/src/app/transport/message-source.js +1 -1
- package/esm/keri/npm/src/app/transport/messengering.js +3 -4
- package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
- package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
- package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
- package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
- package/esm/keri/npm/src/cli/common/context.js +2 -2
- package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
- package/esm/keri/npm/src/cli/common/existing.js +3 -5
- package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
- package/esm/keri/npm/src/cli/credentials/ipex.js +159 -191
- package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
- package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
- package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
- package/esm/keri/npm/src/cli/endpoints/oobi.js +12 -15
- package/esm/keri/npm/src/cli/identity/challenge.js +9 -35
- package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
- package/esm/keri/npm/src/cli/identity/incept.js +17 -34
- package/esm/keri/npm/src/cli/identity/init.js +4 -3
- package/esm/keri/npm/src/cli/identity/interact.js +7 -19
- package/esm/keri/npm/src/cli/identity/rotate.js +10 -38
- package/esm/keri/npm/src/cli/index.js +3 -1
- package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
- package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
- package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
- package/esm/keri/npm/src/cli/messaging/multisig.js +187 -250
- package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
- package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
- package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
- package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
- package/esm/keri/npm/src/core/bytes.js +9 -0
- package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
- package/esm/keri/npm/src/core/kel/eventing.js +67 -12
- package/esm/keri/npm/src/core/kel/kever.js +11 -9
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +41 -9
- package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
- package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
- package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
- package/esm/keri/npm/src/core/records.js +23 -0
- package/esm/keri/npm/src/core/routing.js +15 -2
- package/esm/keri/npm/src/db/basing.js +183 -205
- package/esm/keri/npm/src/db/core/dber.js +1062 -0
- package/esm/keri/npm/src/db/core/index.js +4 -2
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
- package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
- package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
- package/esm/keri/npm/src/db/core/memstore.js +532 -0
- package/esm/keri/npm/src/db/core/path-manager.js +109 -223
- package/esm/keri/npm/src/db/core/store-owner.js +104 -0
- package/esm/keri/npm/src/db/core/webdber.js +252 -0
- package/esm/keri/npm/src/db/escrowing.js +2 -2
- package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
- package/esm/keri/npm/src/db/indexeddb.js +98 -0
- package/esm/keri/npm/src/db/keeping.js +38 -123
- package/esm/keri/npm/src/db/koming.js +1 -1
- package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
- package/esm/keri/npm/src/db/lmdb.js +6 -0
- package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
- package/esm/keri/npm/src/db/noting.js +11 -55
- package/esm/keri/npm/src/db/reger.js +43 -105
- package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
- package/esm/keri/npm/src/db/store-lock.js +150 -0
- package/esm/keri/npm/src/db/subing.js +1 -1
- package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
- package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
- package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
- package/esm/keri/npm/src/npm/db.browser.js +2 -0
- package/esm/keri/npm/src/npm/index.browser.js +9 -0
- package/esm/keri/npm/src/npm/runtime-node.js +3 -0
- package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
- package/esm/keri/npm/src/npm/runtime-web.js +3 -0
- package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
- package/esm/keri/npm/src/runtime/index.js +58 -12
- package/esm/keri/npm/src/runtime/node.js +14 -0
- package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
- package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
- package/esm/keri/npm/src/runtime/web.js +10 -0
- package/esm/keri/npm/src/vdr/eventing.js +1 -1
- package/esm/keri/npm/src/vdr/tel-publication.js +19 -3
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +24 -4
- package/types/acdc/authoring.d.ts +54 -0
- package/types/acdc/authoring.d.ts.map +1 -0
- package/types/acdc/chaining.d.ts +56 -6
- package/types/acdc/chaining.d.ts.map +1 -1
- package/types/acdc/custody.d.ts +77 -0
- package/types/acdc/custody.d.ts.map +1 -0
- package/types/acdc/dhking.d.ts +94 -3
- package/types/acdc/dhking.d.ts.map +1 -1
- package/types/acdc/regbasing.d.ts +11 -6
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/regengine.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +8 -4
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/registraring.d.ts.map +1 -1
- package/types/acdc/salting.d.ts +59 -7
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/acdc/scheming.d.ts +2 -0
- package/types/acdc/scheming.d.ts.map +1 -1
- package/types/acdc/unblinding.d.ts +58 -19
- package/types/acdc/unblinding.d.ts.map +1 -1
- package/types/app/bootstrap/authenticating.d.ts +3 -1
- package/types/app/bootstrap/authenticating.d.ts.map +1 -1
- package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
- package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
- package/types/app/bootstrap/oobiery.d.ts +3 -1
- package/types/app/bootstrap/oobiery.d.ts.map +1 -1
- package/types/app/credentials/credential-revoking.d.ts +3 -0
- package/types/app/credentials/credential-revoking.d.ts.map +1 -1
- package/types/app/credentials/credential-workflows.d.ts +5 -0
- package/types/app/credentials/credential-workflows.d.ts.map +1 -1
- package/types/app/credentials/registry-settling.d.ts +85 -0
- package/types/app/credentials/registry-settling.d.ts.map +1 -0
- package/types/app/credentials/root-replicating.d.ts +97 -0
- package/types/app/credentials/root-replicating.d.ts.map +1 -0
- package/types/app/credentials/root-replicator.d.ts +105 -0
- package/types/app/credentials/root-replicator.d.ts.map +1 -0
- package/types/app/credentials/tel-completion.d.ts +55 -0
- package/types/app/credentials/tel-completion.d.ts.map +1 -0
- package/types/app/credentials/verifying.d.ts +2 -1
- package/types/app/credentials/verifying.d.ts.map +1 -1
- package/types/app/delivery/forwarding.d.ts +16 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts +2 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/challenging.d.ts +54 -0
- package/types/app/identity/challenging.d.ts.map +1 -1
- package/types/app/identity/configing.d.ts +7 -5
- package/types/app/identity/configing.d.ts.map +1 -1
- package/types/app/identity/delegating.d.ts +21 -4
- package/types/app/identity/delegating.d.ts.map +1 -1
- package/types/app/identity/delegation-approval.d.ts +228 -0
- package/types/app/identity/delegation-approval.d.ts.map +1 -0
- package/types/app/identity/event-completion.d.ts +151 -0
- package/types/app/identity/event-completion.d.ts.map +1 -0
- package/types/app/identity/habbing.d.ts +90 -7
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +50 -4
- package/types/app/identity/keeping.d.ts.map +1 -1
- package/types/app/identity/lmdb-habery.d.ts +6 -0
- package/types/app/identity/lmdb-habery.d.ts.map +1 -0
- package/types/app/ipex/group-ipex.d.ts +247 -0
- package/types/app/ipex/group-ipex.d.ts.map +1 -0
- package/types/app/ipex/group-issuance.d.ts +281 -0
- package/types/app/ipex/group-issuance.d.ts.map +1 -0
- package/types/app/ipex/ipex-admitting.d.ts +47 -0
- package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
- package/types/app/ipex/ipex-conversation.d.ts +195 -0
- package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
- package/types/app/ipex/ipex-discloser.d.ts +156 -0
- package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
- package/types/app/ipex/ipex-granting.d.ts +145 -0
- package/types/app/ipex/ipex-granting.d.ts.map +1 -0
- package/types/app/ipex/ipex-graph.d.ts +4 -4
- package/types/app/ipex/ipex-graph.d.ts.map +1 -1
- package/types/app/ipex/ipex-grouping.d.ts +18 -0
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/ipex-v2.d.ts +11 -2
- package/types/app/ipex/ipex-v2.d.ts.map +1 -1
- package/types/app/ipex/ipexing.d.ts +3 -0
- package/types/app/ipex/ipexing.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +443 -0
- package/types/app/ipex/issuance.d.ts.map +1 -0
- package/types/app/ipex/pending-presentations.d.ts +25 -0
- package/types/app/ipex/pending-presentations.d.ts.map +1 -0
- package/types/app/ipex/presentation-files.d.ts +47 -0
- package/types/app/ipex/presentation-files.d.ts.map +1 -0
- package/types/app/ipex/presenting.d.ts +298 -0
- package/types/app/ipex/presenting.d.ts.map +1 -0
- package/types/app/ipex/receive-issuance.d.ts +99 -0
- package/types/app/ipex/receive-issuance.d.ts.map +1 -0
- package/types/app/ipex/unblinding-workflow.d.ts +255 -0
- package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
- package/types/app/mailbox/ipex-arrival.d.ts +104 -0
- package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
- package/types/app/mailbox/kel-publisher.d.ts +141 -0
- package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
- package/types/app/mailbox/kel-publishing.d.ts +70 -0
- package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
- package/types/app/mailbox/kel-submission.d.ts +18 -0
- package/types/app/mailbox/kel-submission.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-admin.d.ts +113 -0
- package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-poller.d.ts +92 -3
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +4 -1
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/counseling.d.ts +196 -0
- package/types/app/multisig/counseling.d.ts.map +1 -0
- package/types/app/multisig/group-members.d.ts +20 -0
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts +39 -20
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +93 -23
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/multisig/proposals.d.ts +129 -0
- package/types/app/multisig/proposals.d.ts.map +1 -0
- package/types/app/multisig/proposing.d.ts +125 -0
- package/types/app/multisig/proposing.d.ts.map +1 -0
- package/types/app/notifications/notifying.d.ts +1 -1
- package/types/app/notifications/notifying.d.ts.map +1 -1
- package/types/app/notifications/signaling.d.ts +3 -1
- package/types/app/notifications/signaling.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +16 -1
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +9 -1
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/queries/query-workflows.d.ts +98 -0
- package/types/app/queries/query-workflows.d.ts.map +1 -0
- package/types/app/runtime/agent-runtime.d.ts +79 -25
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/runtime/cue-runtime.d.ts +2 -1
- package/types/app/runtime/cue-runtime.d.ts.map +1 -1
- package/types/app/runtime/delivery-outbox.d.ts +68 -0
- package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
- package/types/app/runtime/doing.d.ts +27 -0
- package/types/app/runtime/doing.d.ts.map +1 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
- package/types/app/runtime/operation-owners.d.ts +137 -0
- package/types/app/runtime/operation-owners.d.ts.map +1 -0
- package/types/app/runtime/retry-backoff.d.ts +49 -0
- package/types/app/runtime/retry-backoff.d.ts.map +1 -0
- package/types/app/runtime/workflow-contract.d.ts +79 -0
- package/types/app/runtime/workflow-contract.d.ts.map +1 -0
- package/types/app/transport/byte-source.d.ts +13 -10
- package/types/app/transport/byte-source.d.ts.map +1 -1
- package/types/app/transport/cesr-egress.d.ts +21 -7
- package/types/app/transport/cesr-egress.d.ts.map +1 -1
- package/types/app/transport/file-bytes.d.ts +11 -0
- package/types/app/transport/file-bytes.d.ts.map +1 -0
- package/types/app/transport/http-client.d.ts +3 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/app/transport/http-messenger.d.ts +15 -10
- package/types/app/transport/http-messenger.d.ts.map +1 -1
- package/types/app/transport/message-source.d.ts +1 -1
- package/types/app/transport/messengering.d.ts +2 -2
- package/types/app/transport/messengering.d.ts.map +1 -1
- package/types/app/transport/node-http-client.d.ts +10 -0
- package/types/app/transport/node-http-client.d.ts.map +1 -0
- package/types/app/transport/tcp-dialer.d.ts +21 -0
- package/types/app/transport/tcp-dialer.d.ts.map +1 -0
- package/types/cli/common/event-completion.d.ts +26 -0
- package/types/cli/common/event-completion.d.ts.map +1 -0
- package/types/cli/common/existing.d.ts.map +1 -1
- package/types/cli/common/runtime-workers.d.ts +23 -0
- package/types/cli/common/runtime-workers.d.ts.map +1 -0
- package/types/cli/credentials/ipex.d.ts.map +1 -1
- package/types/cli/credentials/vc.d.ts +1 -1
- package/types/cli/credentials/vc.d.ts.map +1 -1
- package/types/cli/endpoints/did.d.ts.map +1 -1
- package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
- package/types/cli/endpoints/oobi.d.ts +3 -1
- package/types/cli/endpoints/oobi.d.ts.map +1 -1
- package/types/cli/identity/challenge.d.ts +1 -1
- package/types/cli/identity/challenge.d.ts.map +1 -1
- package/types/cli/identity/delegate.d.ts +14 -1
- package/types/cli/identity/delegate.d.ts.map +1 -1
- package/types/cli/identity/incept.d.ts.map +1 -1
- package/types/cli/identity/init.d.ts.map +1 -1
- package/types/cli/identity/interact.d.ts.map +1 -1
- package/types/cli/identity/rotate.d.ts.map +1 -1
- package/types/cli/index.d.ts +4 -2
- package/types/cli/index.d.ts.map +1 -1
- package/types/cli/messaging/group-join.d.ts +53 -0
- package/types/cli/messaging/group-join.d.ts.map +1 -0
- package/types/cli/messaging/group-wait.d.ts +34 -0
- package/types/cli/messaging/group-wait.d.ts.map +1 -0
- package/types/cli/messaging/multisig.d.ts +36 -4
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/cli/messaging/root-copy-lines.d.ts +39 -0
- package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
- package/types/cli/tools/annotate.d.ts.map +1 -1
- package/types/cli/tools/benchmark.d.ts.map +1 -1
- package/types/cli/tools/db-dump.d.ts.map +1 -1
- package/types/core/bytes.d.ts +2 -0
- package/types/core/bytes.d.ts.map +1 -1
- package/types/core/cues.d.ts +11 -0
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/kel/delegation-ancestry.d.ts +41 -0
- package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/kel/kever.d.ts +5 -4
- package/types/core/kel/kever.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts +14 -0
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kram-pruning.d.ts +1 -3
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
- package/types/core/mailbox/kraming.d.ts +1 -1
- package/types/core/mailbox/kraming.d.ts.map +1 -1
- package/types/core/records.d.ts +61 -0
- package/types/core/records.d.ts.map +1 -1
- package/types/core/routing.d.ts +6 -0
- package/types/core/routing.d.ts.map +1 -1
- package/types/db/basing.d.ts +22 -25
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/dber.d.ts +505 -0
- package/types/db/core/dber.d.ts.map +1 -0
- package/types/db/core/index.d.ts +4 -2
- package/types/db/core/index.d.ts.map +1 -1
- package/types/db/core/indexeddb-persistence.d.ts +59 -0
- package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
- package/types/db/core/lmdb-opener.d.ts +17 -0
- package/types/db/core/lmdb-opener.d.ts.map +1 -0
- package/types/db/core/lmdber.d.ts +60 -383
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/core/memstore.d.ts +129 -0
- package/types/db/core/memstore.d.ts.map +1 -0
- package/types/db/core/path-manager.d.ts +22 -45
- package/types/db/core/path-manager.d.ts.map +1 -1
- package/types/db/core/store-owner.d.ts +59 -0
- package/types/db/core/store-owner.d.ts.map +1 -0
- package/types/db/core/webdber.d.ts +127 -0
- package/types/db/core/webdber.d.ts.map +1 -0
- package/types/db/escrowing.d.ts +3 -3
- package/types/db/escrowing.d.ts.map +1 -1
- package/types/db/exchange/exchange-nests.d.ts.map +1 -1
- package/types/db/indexeddb.d.ts +37 -0
- package/types/db/indexeddb.d.ts.map +1 -0
- package/types/db/keeping.d.ts +14 -25
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/koming.d.ts +7 -8
- package/types/db/koming.d.ts.map +1 -1
- package/types/db/lmdb-stores.d.ts +45 -0
- package/types/db/lmdb-stores.d.ts.map +1 -0
- package/types/db/lmdb.d.ts +7 -0
- package/types/db/lmdb.d.ts.map +1 -0
- package/types/db/mailbox/mailboxing.d.ts +7 -21
- package/types/db/mailbox/mailboxing.d.ts.map +1 -1
- package/types/db/noting.d.ts +7 -12
- package/types/db/noting.d.ts.map +1 -1
- package/types/db/reger.d.ts +7 -11
- package/types/db/reger.d.ts.map +1 -1
- package/types/db/replay/witness-replay.d.ts +0 -2
- package/types/db/replay/witness-replay.d.ts.map +1 -1
- package/types/db/store-lock.d.ts +72 -0
- package/types/db/store-lock.d.ts.map +1 -0
- package/types/db/subing.d.ts +24 -25
- package/types/db/subing.d.ts.map +1 -1
- package/types/npm/db-indexeddb.d.ts +4 -0
- package/types/npm/db-indexeddb.d.ts.map +1 -0
- package/types/npm/db-lmdb.d.ts +4 -0
- package/types/npm/db-lmdb.d.ts.map +1 -0
- package/types/npm/runtime-node.d.ts +4 -0
- package/types/npm/runtime-node.d.ts.map +1 -0
- package/types/npm/runtime-web.d.ts +4 -0
- package/types/npm/runtime-web.d.ts.map +1 -0
- package/types/runtime/index.d.ts +48 -14
- package/types/runtime/index.d.ts.map +1 -1
- package/types/runtime/node.d.ts +15 -0
- package/types/runtime/node.d.ts.map +1 -0
- package/types/runtime/web/output-barrier.d.ts +30 -0
- package/types/runtime/web/output-barrier.d.ts.map +1 -0
- package/types/runtime/web/persistent-storage.d.ts +36 -0
- package/types/runtime/web/persistent-storage.d.ts.map +1 -0
- package/types/runtime/web.d.ts +11 -0
- package/types/runtime/web.d.ts.map +1 -0
- package/types/vdr/tel-publication.d.ts +6 -0
- package/types/vdr/tel-publication.d.ts.map +1 -1
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/acdc/relating.js +0 -59
- package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
- package/esm/keri/npm/src/db/baser-defaults.js +0 -11
- package/types/acdc/relating.d.ts +0 -21
- package/types/acdc/relating.d.ts.map +0 -1
- package/types/cli/common/tel-completion.d.ts +0 -8
- package/types/cli/common/tel-completion.d.ts.map +0 -1
- package/types/db/baser-defaults.d.ts +0 -5
- package/types/db/baser-defaults.d.ts.map +0 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finite delivery of prepared `/registry/root` copies; transmission is never receipt.
|
|
3
|
+
*
|
|
4
|
+
* `replicateRootCopies` is the KERIpy `rootreplicating.replicate` happy path: a
|
|
5
|
+
* command calls it once a send is possible and reports each typed outcome. There
|
|
6
|
+
* is no acknowledgement or retry here (the runtime's `RootReplicator` derives
|
|
7
|
+
* what is owed and retries); receiving is idempotent, so duplicate copies are
|
|
8
|
+
* harmless.
|
|
9
|
+
*/
|
|
10
|
+
import { parseBytes } from "cesr-ts";
|
|
11
|
+
import { action, race } from "effection";
|
|
12
|
+
import { RootUnverified } from "../../acdc/salting.js";
|
|
13
|
+
import { AppError, ValidationError } from "../../core/errors.js";
|
|
14
|
+
import { CREDENTIAL_MAILBOX_TOPIC } from "../../core/mailbox/mailbox-topics.js";
|
|
15
|
+
import { localGroupMember } from "../multisig/group-members.js";
|
|
16
|
+
/**
|
|
17
|
+
* Send each copy from `sender` to its recipient's `credential` mailbox, in
|
|
18
|
+
* order, and return one outcome per copy. A failed copy does not stop later
|
|
19
|
+
* copies. The caller runs `postman.deliverDo` for the duration; Poster wait
|
|
20
|
+
* misuse or closure still throws.
|
|
21
|
+
*/
|
|
22
|
+
export function* deliverRegistryRoots(postman, sender, copies) {
|
|
23
|
+
const outcomes = [];
|
|
24
|
+
for (const copy of copies) {
|
|
25
|
+
const event = postman.send({ src: sender, dest: copy.recipient, topic: CREDENTIAL_MAILBOX_TOPIC, msg: copy.wire }, { notify: true });
|
|
26
|
+
const outcome = yield* postman.wait(event);
|
|
27
|
+
outcomes.push(outcome.kin === "sent"
|
|
28
|
+
? { kin: "sent", copy, deliveries: outcome.deliveries }
|
|
29
|
+
: { kin: "failed", copy, error: outcome.error });
|
|
30
|
+
}
|
|
31
|
+
return outcomes;
|
|
32
|
+
}
|
|
33
|
+
/** Run `operation` for at most `milliseconds` of `clock` time; null when the budget ends first. */
|
|
34
|
+
function* within(clock, milliseconds, operation) {
|
|
35
|
+
return yield* race([
|
|
36
|
+
operation,
|
|
37
|
+
action(resolve => {
|
|
38
|
+
const timer = clock.setTimeout(() => resolve(null), Math.max(milliseconds, 0));
|
|
39
|
+
return () => clock.clearTimeout(timer);
|
|
40
|
+
}),
|
|
41
|
+
]);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Prepare and deliver one `/registry/root` copy for `gid` from its local member to
|
|
45
|
+
* `recipient`, before `deadline` (epoch ms of `clock`).
|
|
46
|
+
*
|
|
47
|
+
* The copy is sealed with `RegistryRoot.prepare` and a per-registry derived hint
|
|
48
|
+
* (`hinted`, so a copy that could never verify is reported, not sent). Any
|
|
49
|
+
* `AppError` ends in the result; any other exception is an invariant failure and
|
|
50
|
+
* escapes. The caller runs `postman.deliverDo` for the duration.
|
|
51
|
+
*/
|
|
52
|
+
export function* replicateRootCopy(root, postman, clock, gid, registry, recipient, deadline) {
|
|
53
|
+
const sender = localGroupMember(root.hby, gid);
|
|
54
|
+
const result = { kin: "failed", group: gid, registry, sender: sender.pre, recipient };
|
|
55
|
+
try {
|
|
56
|
+
if (clock.now() >= deadline) {
|
|
57
|
+
throw new ValidationError("registry root copies did not complete within their budget");
|
|
58
|
+
}
|
|
59
|
+
let wire;
|
|
60
|
+
try {
|
|
61
|
+
wire = root.prepare(sender, recipient, gid, registry, { hinted: true });
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
result.kin = error instanceof RootUnverified ? "deferred" : "refused";
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
result.exchange = parseBytes(wire)[0].body.said;
|
|
68
|
+
const outcome = yield* within(clock, deadline - clock.now(), deliverRegistryRoots(postman, sender.pre, [{ recipient, wire }]));
|
|
69
|
+
if (!outcome)
|
|
70
|
+
throw new ValidationError("registry root copies did not complete within their budget");
|
|
71
|
+
if (outcome[0].kin === "failed") {
|
|
72
|
+
result.error = outcome[0].error ?? "delivery failed";
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
result.kin = "sent";
|
|
76
|
+
result.deliveries = outcome[0].deliveries;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (!(error instanceof AppError))
|
|
81
|
+
throw error;
|
|
82
|
+
result.error = error;
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Send one copy of each of `registries`' held roots for group `ghab` to each
|
|
88
|
+
* recipient, signed by `ghab`'s local member, and return one result per copy.
|
|
89
|
+
*
|
|
90
|
+
* `recipients` defaults to every other current signing member. `timeoutMs` is this
|
|
91
|
+
* replication's own budget: a copy reached after it ends, or still sending when it
|
|
92
|
+
* ends, is `failed`. Nothing is retried or recorded and an `AppError` never
|
|
93
|
+
* escapes. The caller runs `postman.deliverDo` for the duration.
|
|
94
|
+
*/
|
|
95
|
+
export function* replicateRootCopies(root, postman, clock, ghab, registries, { recipients, timeoutMs }) {
|
|
96
|
+
const gid = ghab.pre, sender = localGroupMember(root.hby, gid), deadline = clock.now() + Math.max(timeoutMs, 0);
|
|
97
|
+
const targets = recipients ?? root.members(gid).filter(aid => aid !== sender.pre);
|
|
98
|
+
const results = [];
|
|
99
|
+
for (const registry of registries) {
|
|
100
|
+
for (const recipient of targets) {
|
|
101
|
+
results.push(yield* replicateRootCopy(root, postman, clock, gid, registry, recipient, deadline));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return results;
|
|
105
|
+
}
|
|
106
|
+
/** Budget for re-seal copies from a command without its own `--timeout`, as KERIpy `rootreplicating.Budget`. */
|
|
107
|
+
export const RootResealBudgetMs = 30_000;
|
|
108
|
+
/**
|
|
109
|
+
* After an accepted group rotation, send held roots to new or rekeyed members.
|
|
110
|
+
*
|
|
111
|
+
* Only a signer of the rotation that held a prior key sends (`RegistryRoot.resealed`),
|
|
112
|
+
* every such signer sends with no election, and a member holding no root for the
|
|
113
|
+
* group sends nothing. `examination` is set when the recipients could not be
|
|
114
|
+
* selected, and then nothing is sent. Fire and forget like `replicateRootCopies`.
|
|
115
|
+
*/
|
|
116
|
+
export function* resealRootCopies(root, postman, clock, ghab, rotation, { timeoutMs = RootResealBudgetMs } = {}) {
|
|
117
|
+
let recipients;
|
|
118
|
+
try {
|
|
119
|
+
recipients = root.resealed(ghab, rotation);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (!(error instanceof AppError))
|
|
123
|
+
throw error;
|
|
124
|
+
return { examination: { group: ghab.pre, rotation, error }, copies: [] };
|
|
125
|
+
}
|
|
126
|
+
const registries = root.held(ghab.pre);
|
|
127
|
+
if (!recipients.length || !registries.length)
|
|
128
|
+
return { examination: null, copies: [] };
|
|
129
|
+
const copies = yield* replicateRootCopies(root, postman, clock, ghab, registries, { recipients, timeoutMs });
|
|
130
|
+
return { examination: null, copies };
|
|
131
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _RootReplicator_instances, _RootReplicator_deps, _RootReplicator_pending, _RootReplicator_inflight, _RootReplicator_seen, _RootReplicator_dirty, _RootReplicator_pruned, _RootReplicator_attempt, _RootReplicator_refreshDirty, _RootReplicator_derive;
|
|
13
|
+
import { isLocalGroupHab, localGroupMember } from "../multisig/group-members.js";
|
|
14
|
+
import { replicateRootCopy, RootResealBudgetMs } from "./root-replicating.js";
|
|
15
|
+
/** Most copies one `processOnce` attempts, so a first pass over a large store cannot stall the runtime. */
|
|
16
|
+
export const RootSendsPerPass = 4;
|
|
17
|
+
/** Process-local retry delay after a copy's first failed attempt; doubles per attempt up to {@link RootRetryMaxMs}. */
|
|
18
|
+
export const RootRetryBaseMs = 1_000;
|
|
19
|
+
export const RootRetryMaxMs = 300_000;
|
|
20
|
+
const idOf = (group, registry, recipient) => [group, registry, recipient].join("/");
|
|
21
|
+
/**
|
|
22
|
+
* Derives, sends and records registry root copies for a wallet's local groups.
|
|
23
|
+
*
|
|
24
|
+
* Holds no durable state of its own beyond `Baser.rrsn`; what is pending and the
|
|
25
|
+
* backoff are process-local and rebuilt from state. A host calls `prompt` (or
|
|
26
|
+
* `replicate`) for each Dhke cue and `processOnce` on its loop; both are safe to repeat,
|
|
27
|
+
* and overlapping `processOnce` calls never send one copy twice.
|
|
28
|
+
*/
|
|
29
|
+
export class RootReplicator {
|
|
30
|
+
constructor(deps) {
|
|
31
|
+
_RootReplicator_instances.add(this);
|
|
32
|
+
_RootReplicator_deps.set(this, void 0);
|
|
33
|
+
_RootReplicator_pending.set(this, new Map());
|
|
34
|
+
_RootReplicator_inflight.set(this, new Set());
|
|
35
|
+
_RootReplicator_seen.set(this, new Map());
|
|
36
|
+
_RootReplicator_dirty.set(this, new Set());
|
|
37
|
+
_RootReplicator_pruned.set(this, false);
|
|
38
|
+
__classPrivateFieldSet(this, _RootReplicator_deps, deps, "f");
|
|
39
|
+
}
|
|
40
|
+
/** Re-derive `group`'s owed copies on the next pass and retry its failed copies at once. */
|
|
41
|
+
prompt(group) {
|
|
42
|
+
__classPrivateFieldGet(this, _RootReplicator_dirty, "f").add(group);
|
|
43
|
+
for (const entry of __classPrivateFieldGet(this, _RootReplicator_pending, "f").values())
|
|
44
|
+
if (entry.group === group)
|
|
45
|
+
entry.retryAt = 0;
|
|
46
|
+
}
|
|
47
|
+
/** The Dhke completion cue: a prompt to run the pass now, not the source of truth. */
|
|
48
|
+
replicate(cue) {
|
|
49
|
+
this.prompt(cue.gid);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Derive what is owed, then send up to {@link RootSendsPerPass} due copies within
|
|
53
|
+
* `timeoutMs`. A copy is recorded when sent and kept for retry otherwise. Never throws
|
|
54
|
+
* on a remote failure; every attempt is returned. The host runs `postman.deliverDo`.
|
|
55
|
+
*/
|
|
56
|
+
*processOnce({ timeoutMs = RootResealBudgetMs } = {}) {
|
|
57
|
+
this.sweep();
|
|
58
|
+
return yield* this.processDue({ timeoutMs });
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The fixed-tock pass: re-derive only the groups that were prompted, then send up to {@link RootSendsPerPass}
|
|
62
|
+
* due copies. A rotation nobody prompted for waits for {@link RootReplicator.sweep}.
|
|
63
|
+
*/
|
|
64
|
+
*processDue({ timeoutMs = RootResealBudgetMs } = {}) {
|
|
65
|
+
const { clock } = __classPrivateFieldGet(this, _RootReplicator_deps, "f"), deadline = clock.now() + Math.max(timeoutMs, 0);
|
|
66
|
+
__classPrivateFieldGet(this, _RootReplicator_instances, "m", _RootReplicator_refreshDirty).call(this);
|
|
67
|
+
const results = [];
|
|
68
|
+
for (const entry of [...__classPrivateFieldGet(this, _RootReplicator_pending, "f").values()]) {
|
|
69
|
+
if (results.length >= RootSendsPerPass)
|
|
70
|
+
break;
|
|
71
|
+
if (entry.retryAt > clock.now())
|
|
72
|
+
continue;
|
|
73
|
+
const result = yield* __classPrivateFieldGet(this, _RootReplicator_instances, "m", _RootReplicator_attempt).call(this, entry.group, entry.registry, entry.recipient, deadline);
|
|
74
|
+
if (!result)
|
|
75
|
+
continue;
|
|
76
|
+
results.push(result);
|
|
77
|
+
if (result.kin === "sent") {
|
|
78
|
+
__classPrivateFieldGet(this, _RootReplicator_pending, "f").delete(idOf(entry.group, entry.registry, entry.recipient));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
entry.attempts += 1;
|
|
82
|
+
entry.lastFailure = result.error;
|
|
83
|
+
entry.retryAt = clock.now() + Math.min(RootRetryBaseMs * 2 ** (entry.attempts - 1), RootRetryMaxMs);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return results;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Send each registry's root to each recipient now, whatever was sent before, as an
|
|
90
|
+
* explicit command does; a sent copy is recorded like any other. `recipients` defaults
|
|
91
|
+
* to every other current signing member.
|
|
92
|
+
*/
|
|
93
|
+
*send(ghab, registries, { recipients, timeoutMs }) {
|
|
94
|
+
const { root, clock } = __classPrivateFieldGet(this, _RootReplicator_deps, "f"), gid = ghab.pre, deadline = clock.now() + Math.max(timeoutMs, 0);
|
|
95
|
+
const sender = localGroupMember(root.hby, gid).pre;
|
|
96
|
+
const targets = recipients ?? root.members(gid).filter(aid => aid !== sender);
|
|
97
|
+
const results = [];
|
|
98
|
+
for (const registry of registries) {
|
|
99
|
+
for (const recipient of targets) {
|
|
100
|
+
const result = yield* __classPrivateFieldGet(this, _RootReplicator_instances, "m", _RootReplicator_attempt).call(this, gid, registry, recipient, deadline);
|
|
101
|
+
if (result)
|
|
102
|
+
results.push(result);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
/** Whether a copy is owed or a group is waiting to be re-derived; in memory, reads no store. */
|
|
108
|
+
pending() {
|
|
109
|
+
return __classPrivateFieldGet(this, _RootReplicator_pending, "f").size > 0 || __classPrivateFieldGet(this, _RootReplicator_dirty, "f").size > 0;
|
|
110
|
+
}
|
|
111
|
+
/** Pure read: what is owed and why it has not gone yet. */
|
|
112
|
+
status() {
|
|
113
|
+
return {
|
|
114
|
+
owed: [...__classPrivateFieldGet(this, _RootReplicator_pending, "f").values()].map(({ retryAt: _retryAt, ...entry }) => ({ ...entry })),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The full check: drop markers of groups that are gone (once) and re-derive each local group that is new or
|
|
119
|
+
* whose establishment event changed. One keyed read per local identifier, so a host runs it every
|
|
120
|
+
* many tocks, not every tock.
|
|
121
|
+
*/
|
|
122
|
+
sweep() {
|
|
123
|
+
const { root } = __classPrivateFieldGet(this, _RootReplicator_deps, "f"), hby = root.hby;
|
|
124
|
+
if (!__classPrivateFieldGet(this, _RootReplicator_pruned, "f")) {
|
|
125
|
+
__classPrivateFieldSet(this, _RootReplicator_pruned, true, "f");
|
|
126
|
+
for (const [[group]] of [...hby.db.rrsn.getTopItemIter()]) {
|
|
127
|
+
if (!hby.db.getHab(group)?.mid)
|
|
128
|
+
hby.db.rrsn.trim(group, { topive: true });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const hab of hby.habs.values()) {
|
|
132
|
+
const established = hab.pre && isLocalGroupHab(hby, hab) ? hab.kever?.lastEst.d : null;
|
|
133
|
+
if (!established || (__classPrivateFieldGet(this, _RootReplicator_seen, "f").get(hab.pre) === established && !__classPrivateFieldGet(this, _RootReplicator_dirty, "f").has(hab.pre)))
|
|
134
|
+
continue;
|
|
135
|
+
__classPrivateFieldGet(this, _RootReplicator_seen, "f").set(hab.pre, established);
|
|
136
|
+
__classPrivateFieldGet(this, _RootReplicator_dirty, "f").delete(hab.pre);
|
|
137
|
+
__classPrivateFieldGet(this, _RootReplicator_instances, "m", _RootReplicator_derive).call(this, hab.pre);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
_RootReplicator_deps = new WeakMap(), _RootReplicator_pending = new WeakMap(), _RootReplicator_inflight = new WeakMap(), _RootReplicator_seen = new WeakMap(), _RootReplicator_dirty = new WeakMap(), _RootReplicator_pruned = new WeakMap(), _RootReplicator_instances = new WeakSet(), _RootReplicator_attempt = function
|
|
142
|
+
/** Deliver one copy unless an overlapping call already is; record it when sent. */
|
|
143
|
+
* _RootReplicator_attempt(group, registry, recipient, deadline) {
|
|
144
|
+
const { root, postman, clock, changes } = __classPrivateFieldGet(this, _RootReplicator_deps, "f"), id = idOf(group, registry, recipient);
|
|
145
|
+
if (__classPrivateFieldGet(this, _RootReplicator_inflight, "f").has(id))
|
|
146
|
+
return null;
|
|
147
|
+
__classPrivateFieldGet(this, _RootReplicator_inflight, "f").add(id);
|
|
148
|
+
try {
|
|
149
|
+
const key = root.contributor(group, recipient);
|
|
150
|
+
const result = yield* replicateRootCopy(root, postman, clock, group, registry, recipient, deadline);
|
|
151
|
+
if (result.kin === "sent" && key) {
|
|
152
|
+
root.hby.db.rrsn.pin([group, registry, recipient], { key, dt: new Date(clock.now()).toISOString() });
|
|
153
|
+
}
|
|
154
|
+
changes?.push({ kind: "group", id: group });
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
__classPrivateFieldGet(this, _RootReplicator_inflight, "f").delete(id);
|
|
159
|
+
}
|
|
160
|
+
}, _RootReplicator_refreshDirty = function _RootReplicator_refreshDirty() {
|
|
161
|
+
const hby = __classPrivateFieldGet(this, _RootReplicator_deps, "f").root.hby;
|
|
162
|
+
for (const group of [...__classPrivateFieldGet(this, _RootReplicator_dirty, "f")]) {
|
|
163
|
+
const hab = hby.habs.get(group);
|
|
164
|
+
const established = hab && isLocalGroupHab(hby, hab) ? hab.kever?.lastEst.d : null;
|
|
165
|
+
__classPrivateFieldGet(this, _RootReplicator_dirty, "f").delete(group);
|
|
166
|
+
if (!established)
|
|
167
|
+
continue;
|
|
168
|
+
__classPrivateFieldGet(this, _RootReplicator_seen, "f").set(group, established);
|
|
169
|
+
__classPrivateFieldGet(this, _RootReplicator_instances, "m", _RootReplicator_derive).call(this, group);
|
|
170
|
+
}
|
|
171
|
+
}, _RootReplicator_derive = function _RootReplicator_derive(group) {
|
|
172
|
+
const { root, changes } = __classPrivateFieldGet(this, _RootReplicator_deps, "f"), db = root.hby.db;
|
|
173
|
+
const sender = localGroupMember(root.hby, group).pre, registries = root.held(group);
|
|
174
|
+
const members = root.members(group).filter(aid => aid !== sender);
|
|
175
|
+
const wanted = new Set();
|
|
176
|
+
for (const registry of registries) {
|
|
177
|
+
for (const recipient of members) {
|
|
178
|
+
const id = idOf(group, registry, recipient);
|
|
179
|
+
wanted.add(id);
|
|
180
|
+
if (db.rrsn.get([group, registry, recipient])?.key === root.contributor(group, recipient)) {
|
|
181
|
+
__classPrivateFieldGet(this, _RootReplicator_pending, "f").delete(id);
|
|
182
|
+
}
|
|
183
|
+
else if (!__classPrivateFieldGet(this, _RootReplicator_pending, "f").has(id)) {
|
|
184
|
+
__classPrivateFieldGet(this, _RootReplicator_pending, "f").set(id, { group, registry, recipient, attempts: 0, lastFailure: null, retryAt: 0 });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
for (const [id, entry] of [...__classPrivateFieldGet(this, _RootReplicator_pending, "f")]) {
|
|
189
|
+
if (entry.group === group && !wanted.has(id))
|
|
190
|
+
__classPrivateFieldGet(this, _RootReplicator_pending, "f").delete(id);
|
|
191
|
+
}
|
|
192
|
+
for (const [[, registry, recipient]] of [...db.rrsn.getTopItemIter(group, { topive: true })]) {
|
|
193
|
+
if (!wanted.has(idOf(group, registry, recipient)))
|
|
194
|
+
db.rrsn.rem([group, registry, recipient]);
|
|
195
|
+
}
|
|
196
|
+
if (wanted.size)
|
|
197
|
+
changes?.push({ kind: "group", id: group });
|
|
198
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { systemClock } from "../runtime/runtime-clock.js";
|
|
2
|
+
import { observeUntil } from "../runtime/workflow-contract.js";
|
|
3
|
+
/** Elapsed milliseconds between reads of a TEL wait. */
|
|
4
|
+
export const TEL_WAIT_POLL_MS = 50;
|
|
5
|
+
/** Read the status of the TEL event `pre` at `sn`; mutates nothing. */
|
|
6
|
+
export function telEventStatus(deps, pre, sn = 0) {
|
|
7
|
+
const progress = deps.publication.progress(pre, sn);
|
|
8
|
+
if (progress === null)
|
|
9
|
+
return { state: "unknown", reason: "not-tracked" };
|
|
10
|
+
return progress === "complete" ? { state: "complete" } : { state: "active", phase: progress };
|
|
11
|
+
}
|
|
12
|
+
/** Status of an issued credential: its TEL issuance event plus saved credential evidence. */
|
|
13
|
+
export function issuedCredentialStatus(deps, said) {
|
|
14
|
+
const status = telEventStatus(deps, said, 0);
|
|
15
|
+
if (status.state === "complete" && deps.publication.reger.saved.get(said) === null) {
|
|
16
|
+
return { state: "active", phase: "awaitingCredentialSave" };
|
|
17
|
+
}
|
|
18
|
+
return status;
|
|
19
|
+
}
|
|
20
|
+
function* observe(read, { deadline, clock = systemClock }) {
|
|
21
|
+
const done = yield* observeUntil(() => read().state === "complete", {
|
|
22
|
+
timeoutMs: Math.max(0, deadline - clock.now()),
|
|
23
|
+
clock,
|
|
24
|
+
pollMs: TEL_WAIT_POLL_MS,
|
|
25
|
+
});
|
|
26
|
+
const status = read();
|
|
27
|
+
return done ? { outcome: "settled", status } : { outcome: "timed-out", status, deadline };
|
|
28
|
+
}
|
|
29
|
+
/** Observe one exact TEL coordinate until complete or the deadline passes. Starts no worker. */
|
|
30
|
+
export function* waitForTelEvent(deps, pre, sn, options) {
|
|
31
|
+
return yield* observe(() => telEventStatus(deps, pre, sn), options);
|
|
32
|
+
}
|
|
33
|
+
/** Observe an issuance until its TEL event is complete and the credential is saved. Starts no worker. */
|
|
34
|
+
export function* waitForIssuedCredential(deps, said, options) {
|
|
35
|
+
return yield* observe(() => issuedCredentialStatus(deps, said), options);
|
|
36
|
+
}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* TypeScript divergence:
|
|
9
9
|
* - ordinary outcomes are explicit decisions instead of exception-only control
|
|
10
|
-
* flow; durable corruption and unsupported `DI2I` still
|
|
10
|
+
* flow; durable corruption and unsupported delegated `DI2I`/`DI1I` still
|
|
11
|
+
* fail explicitly
|
|
11
12
|
*/
|
|
12
13
|
import { Dater, Ilks, Saider, } from "cesr-ts";
|
|
13
14
|
import { Deck } from "../../core/deck.js";
|
|
@@ -268,10 +269,18 @@ export class Verifier {
|
|
|
268
269
|
}
|
|
269
270
|
const attrib = creder.attrib;
|
|
270
271
|
let operator = op;
|
|
271
|
-
if (operator
|
|
272
|
+
if (operator === "I1I" || operator === "DI1I") {
|
|
273
|
+
// Issuer identity suppresses the issuee default and never reads issuees.
|
|
274
|
+
if (creder.issuer !== issuer) {
|
|
275
|
+
if (operator === "I1I")
|
|
276
|
+
return null;
|
|
277
|
+
throw new ValidationError("DI1I credential chain verification is not implemented.");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (operator !== "I2I" && operator !== "DI2I" && operator !== "NI2I") {
|
|
272
281
|
operator = isRecord(attrib) && typeof attrib.i === "string" ? "I2I" : "NI2I";
|
|
273
282
|
}
|
|
274
|
-
if (operator
|
|
283
|
+
if (operator === "I2I" || operator === "DI2I") {
|
|
275
284
|
if (!isRecord(attrib) || typeof attrib.i !== "string") {
|
|
276
285
|
return null;
|
|
277
286
|
}
|
|
@@ -7,13 +7,36 @@ import { exchange } from "../../core/exchange/protocol-exchanging.js";
|
|
|
7
7
|
import { Roles } from "../../core/roles.js";
|
|
8
8
|
import { mailboxTopicKey, preferredUrl } from "../mailbox/mailboxing.js";
|
|
9
9
|
import { transportMailboxTopic } from "../mailbox/topic-routing.js";
|
|
10
|
+
import { localGroupMember } from "../multisig/group-members.js";
|
|
10
11
|
import { abortable } from "../runtime/abortable.js";
|
|
11
12
|
import { runtimeTurn } from "../runtime/runtime-turn.js";
|
|
12
13
|
import { CesrHttpRefusal } from "../transport/cesr-egress.js";
|
|
13
14
|
import { messengerFrom, streamMessengerFrom } from "../transport/messengering.js";
|
|
14
|
-
import {
|
|
15
|
+
import { requireTcpDialer } from "../transport/tcp-dialer.js";
|
|
15
16
|
import { TransportError } from "../transport/transport-error.js";
|
|
16
17
|
import { introduce } from "./introducing.js";
|
|
18
|
+
/**
|
|
19
|
+
* A v2 message refused for a peer this node must treat as v1.
|
|
20
|
+
*
|
|
21
|
+
* A v1 parser treats a v2 version string as an extraction failure and discards the rest of
|
|
22
|
+
* its stream, so sending would lose more than this one message.
|
|
23
|
+
*/
|
|
24
|
+
export class PeerVersionError extends ValidationError {
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether an AID's own accepted KEL ends in a v1 event, which is the only evidence of a v1 reader.
|
|
28
|
+
*
|
|
29
|
+
* An AID with no accepted KEL is not refused. A delegate awaiting approval has only an escrowed
|
|
30
|
+
* inception, and refusing its approval traffic would stop the delegation from ever completing.
|
|
31
|
+
*/
|
|
32
|
+
function knownV1Peer(hby, aid) {
|
|
33
|
+
const kever = hby.db.getKever(aid);
|
|
34
|
+
return kever !== null && kever !== undefined && kever.serder.pvrsn.major < 2;
|
|
35
|
+
}
|
|
36
|
+
/** Whether any frame of this complete signed wire needs a v2 reader. */
|
|
37
|
+
function wireNeedsV2(message) {
|
|
38
|
+
return parseBytes(message).some(frame => frame.body.pvrsn.major >= 2 || (frame.gvrsn?.major ?? 1) >= 2);
|
|
39
|
+
}
|
|
17
40
|
/**
|
|
18
41
|
* Preserve resolved endpoint schemes and signed bytes for concrete transport construction.
|
|
19
42
|
*
|
|
@@ -374,11 +397,20 @@ export class Poster {
|
|
|
374
397
|
failed.push(new ValidationError(`No supported endpoint URL for ${endpoint.eid}.`));
|
|
375
398
|
continue;
|
|
376
399
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
400
|
+
let target;
|
|
401
|
+
try {
|
|
402
|
+
target = yield* this.prepareBytesTarget(hab, route, {
|
|
403
|
+
eid: endpoint.eid,
|
|
404
|
+
url: endpoint.url,
|
|
405
|
+
urls: endpoint.urls,
|
|
406
|
+
}, evt);
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
if (!(error instanceof PeerVersionError))
|
|
410
|
+
throw error;
|
|
411
|
+
failed.push(error);
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
382
414
|
try {
|
|
383
415
|
if (target.kind !== "stored") {
|
|
384
416
|
const refusal = yield* this.sendPreparedTarget(target, evt, signal);
|
|
@@ -416,7 +448,7 @@ export class Poster {
|
|
|
416
448
|
*sendPreparedTarget(target, evt, signal) {
|
|
417
449
|
if (target.kind === "tcp" && evt.replies) {
|
|
418
450
|
// Explicit duplex work retains its receive owner; send-only factories need none.
|
|
419
|
-
yield*
|
|
451
|
+
yield* requireTcpDialer(this.http).messenger(target.url, this.clock, this.protocol).send(target.message, {
|
|
420
452
|
signal,
|
|
421
453
|
replies: true,
|
|
422
454
|
});
|
|
@@ -474,6 +506,15 @@ export class Poster {
|
|
|
474
506
|
};
|
|
475
507
|
});
|
|
476
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* Whether `src` has any eligible role (controller, agent, mailbox or witness) from which to reach `dest`, as
|
|
511
|
+
* delivery would find it now. A pure read of accepted endpoint state: it says nothing about whether the
|
|
512
|
+
* endpoint answers. A proposer uses it to refuse before it creates anything it could not publish.
|
|
513
|
+
*/
|
|
514
|
+
canReach(src, dest, topic = "multisig") {
|
|
515
|
+
const hab = this.hby.habs.get(src);
|
|
516
|
+
return !!hab && this.findBytesRoutes(hab, dest, topic).length > 0;
|
|
517
|
+
}
|
|
477
518
|
/**
|
|
478
519
|
* Prepare a target using the supplied wire and selected endpoint.
|
|
479
520
|
*
|
|
@@ -482,11 +523,18 @@ export class Poster {
|
|
|
482
523
|
* @param endpoint One selected endpoint AID and URL from the route.
|
|
483
524
|
* @param evt Original signed source and concrete ordinary/stream operation.
|
|
484
525
|
* @returns A prepared remote target, or stored after authorized local mailbox publication.
|
|
526
|
+
* @throws PeerVersionError when the wire needs a v2 reader that this peer is known not to be.
|
|
485
527
|
*/
|
|
486
528
|
*prepareBytesTarget(hab, route, endpoint, evt) {
|
|
529
|
+
if (wireNeedsV2(evt.msg) && knownV1Peer(this.hby, evt.dest)) {
|
|
530
|
+
throw new PeerVersionError(`Refusing a v2 message for ${evt.dest}, whose latest accepted event is v1.`);
|
|
531
|
+
}
|
|
487
532
|
if (route.kind !== "direct") {
|
|
488
533
|
return yield* this.prepareForwardedTarget(hab, evt.dest, evt.topic, evt, endpoint);
|
|
489
534
|
}
|
|
535
|
+
if (wireNeedsV2(evt.msg) && knownV1Peer(this.hby, endpoint.eid)) {
|
|
536
|
+
throw new PeerVersionError(`Refusing a v2 message for endpoint ${endpoint.eid}, whose latest accepted event is v1.`);
|
|
537
|
+
}
|
|
490
538
|
return remoteCesrTarget(endpoint, evt.msg);
|
|
491
539
|
}
|
|
492
540
|
/**
|
|
@@ -506,6 +554,9 @@ export class Poster {
|
|
|
506
554
|
throw new Error("Mailbox publication did not complete");
|
|
507
555
|
return { kind: "stored" };
|
|
508
556
|
}
|
|
557
|
+
// A group cannot sign the wrapper alone: one member's signature does not meet a threshold above one, and the
|
|
558
|
+
// host would escrow the wrapper. The local member wraps; the payload keeps whatever signatures it carries.
|
|
559
|
+
const signer = this.hby.db.groups.has(hab.pre) ? localGroupMember(this.hby, hab.pre) : hab;
|
|
509
560
|
const msgs = [];
|
|
510
561
|
if (evt.kin === "stream") {
|
|
511
562
|
// Prepare every frame before opening the one selected relay attempt.
|
|
@@ -516,10 +567,14 @@ export class Poster {
|
|
|
516
567
|
else {
|
|
517
568
|
msgs.push(evt.msg);
|
|
518
569
|
}
|
|
570
|
+
// The provider reads the envelope, so it must read v2 whenever the envelope or child is v2.
|
|
571
|
+
if ((signer.kelVersion.major >= 2 || msgs.some(wireNeedsV2)) && knownV1Peer(this.hby, endpoint.eid)) {
|
|
572
|
+
throw new PeerVersionError(`Refusing a v2 envelope for provider ${endpoint.eid}, whose latest accepted event is v1.`);
|
|
573
|
+
}
|
|
519
574
|
const forwarded = [];
|
|
520
575
|
for (const message of msgs)
|
|
521
|
-
forwarded.push(yield* buildForwardedDelivery(
|
|
522
|
-
const intro = introduce(
|
|
576
|
+
forwarded.push(yield* buildForwardedDelivery(signer, { recipient, topic, message }));
|
|
577
|
+
const intro = introduce(signer, endpoint.eid);
|
|
523
578
|
let message = concatBytes(intro, ...forwarded);
|
|
524
579
|
if (evt.kin === "stream") {
|
|
525
580
|
const frames = parseBytes(message);
|
|
@@ -13,6 +13,7 @@ import { hasNests, loadNests, prepareNests, publishNests } from "../../db/exchan
|
|
|
13
13
|
import { encodeDateTimeToDater, makeNowIso8601, timestampMicros } from "../../time/mod.js";
|
|
14
14
|
import { groupMemberHasKey } from "../multisig/group-members.js";
|
|
15
15
|
import { abortable } from "../runtime/abortable.js";
|
|
16
|
+
import { runtimeTurn } from "../runtime/runtime-turn.js";
|
|
16
17
|
const textDecoder = new TextDecoder();
|
|
17
18
|
const EXCHANGE_ESCROW_TIMEOUT_MS = 10_000;
|
|
18
19
|
/** CESR syntax failures identify malformed evidence; I/O, limits, and hashing failures do not. */
|
|
@@ -142,8 +143,11 @@ export class Exchanger {
|
|
|
142
143
|
}
|
|
143
144
|
/** Resolve the configured body-version route owner without dispatching or changing evidence. */
|
|
144
145
|
handlerFor(serder) {
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
return this.routeHandler(serder.route ?? "", serder.pvrsn.major);
|
|
147
|
+
}
|
|
148
|
+
/** Resolve the owner one route and protocol major would dispatch to, without a message body. */
|
|
149
|
+
routeHandler(route, major) {
|
|
150
|
+
return this.versionedRoutes.get(route)?.get(major) ?? this.routes.get(route);
|
|
147
151
|
}
|
|
148
152
|
/**
|
|
149
153
|
* Verify, persist, and dispatch one inbound `exn`.
|
|
@@ -209,7 +213,8 @@ export class Exchanger {
|
|
|
209
213
|
const nests = args.nests?.length
|
|
210
214
|
? yield* abortable((signal) => prepareNests(args.nests, signal))
|
|
211
215
|
: undefined;
|
|
212
|
-
const
|
|
216
|
+
const written = this.hby.db.writeVersion;
|
|
217
|
+
const result = this.hby.db.transaction(() => {
|
|
213
218
|
if (selectedGrant) {
|
|
214
219
|
const db = this.hby.db;
|
|
215
220
|
const stored = selectedGrant === "proof" ? db.epse.get([said]) : db.exns.get([said]) ?? db.epse.get([said]);
|
|
@@ -267,10 +272,9 @@ export class Exchanger {
|
|
|
267
272
|
}
|
|
268
273
|
return admission;
|
|
269
274
|
});
|
|
270
|
-
// Durable completion joins the actual LMDB flush;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
});
|
|
275
|
+
// Durable completion joins the actual LMDB flush; a transaction that wrote nothing has nothing to wait for.
|
|
276
|
+
if (this.hby.db.writeVersion !== written)
|
|
277
|
+
yield* this.hby.db.flushed();
|
|
274
278
|
if (!result)
|
|
275
279
|
return undefined;
|
|
276
280
|
for (const cue of result.cues)
|
|
@@ -405,11 +409,16 @@ export class Exchanger {
|
|
|
405
409
|
// False means an existing qualified member, not a failed write. Exceptions abort the writer.
|
|
406
410
|
for (const texter of args.essrs ?? [])
|
|
407
411
|
this.hby.db.essrs.add([said], texter);
|
|
408
|
-
|
|
412
|
+
const meta = {
|
|
409
413
|
mailboxAid,
|
|
410
414
|
...(receiverTime !== undefined ? { receiverTime } : {}),
|
|
411
415
|
gvrsn: previous?.gvrsn ?? args.gvrsn ?? args.serder.gvrsn ?? args.serder.pvrsn,
|
|
412
|
-
}
|
|
416
|
+
};
|
|
417
|
+
// A retry that learns nothing new leaves the stored record as it is rather than committing it again.
|
|
418
|
+
if (!previous || previous.mailboxAid !== meta.mailboxAid || previous.receiverTime !== meta.receiverTime
|
|
419
|
+
|| JSON.stringify(previous.gvrsn) !== JSON.stringify(meta.gvrsn)) {
|
|
420
|
+
this.hby.db.exchangeMeta.pin([said], meta);
|
|
421
|
+
}
|
|
413
422
|
if (pending) {
|
|
414
423
|
if (newEscrow) {
|
|
415
424
|
if (senderQuery)
|
|
@@ -448,7 +457,7 @@ export class Exchanger {
|
|
|
448
457
|
const table = schema ? this.hby.db.emse : this.hby.db.epse;
|
|
449
458
|
let end;
|
|
450
459
|
// Capture a finite key horizon without retaining bodies or holding a cursor across mutations.
|
|
451
|
-
for (const key of table.sdb
|
|
460
|
+
for (const key of this.hby.db.scanKeys(table.sdb, { reverse: true, limit: 1 })) {
|
|
452
461
|
end = b(`${textDecoder.decode(key)}\0`);
|
|
453
462
|
}
|
|
454
463
|
if (!end) {
|
|
@@ -457,7 +466,7 @@ export class Exchanger {
|
|
|
457
466
|
let start;
|
|
458
467
|
for (;;) {
|
|
459
468
|
let physical;
|
|
460
|
-
for (const key of table.sdb
|
|
469
|
+
for (const key of this.hby.db.scanKeys(table.sdb, { start, end, limit: 1 })) {
|
|
461
470
|
physical = textDecoder.decode(key);
|
|
462
471
|
}
|
|
463
472
|
if (!physical)
|
|
@@ -491,6 +500,8 @@ export class Exchanger {
|
|
|
491
500
|
...attempt.ejection,
|
|
492
501
|
});
|
|
493
502
|
}
|
|
503
|
+
// Deliveries and I/O take a slot between escrowed messages; none is skipped.
|
|
504
|
+
yield* runtimeTurn();
|
|
494
505
|
}
|
|
495
506
|
}
|
|
496
507
|
/**
|
|
@@ -1291,7 +1302,7 @@ export class Exchanger {
|
|
|
1291
1302
|
/** Decide expiry and remove pending rows in the same native transaction. */
|
|
1292
1303
|
*expirePending(serder) {
|
|
1293
1304
|
const said = serder.said;
|
|
1294
|
-
const result = this.hby.db.
|
|
1305
|
+
const result = this.hby.db.transaction(() => {
|
|
1295
1306
|
const status = this.escrowStatus(said);
|
|
1296
1307
|
if (status.kind === "accepted") {
|
|
1297
1308
|
this.clearPending(serder);
|
|
@@ -1301,9 +1312,7 @@ export class Exchanger {
|
|
|
1301
1312
|
return undefined;
|
|
1302
1313
|
return this.retireCurrent(serder, this.expiryReport(status));
|
|
1303
1314
|
});
|
|
1304
|
-
yield*
|
|
1305
|
-
await this.hby.db.env.flushed;
|
|
1306
|
-
});
|
|
1315
|
+
yield* this.hby.db.flushed();
|
|
1307
1316
|
return result;
|
|
1308
1317
|
}
|
|
1309
1318
|
/** Clear only dependency markers, keeping all accepted evidence and metadata intact. */
|