@optimystic/db-p2p 0.24.1 → 0.25.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 → README.md} +688 -668
- package/dist/src/cluster/block-transfer-service.d.ts +133 -10
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +155 -9
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/block-transfer.d.ts +67 -7
- package/dist/src/cluster/block-transfer.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer.js +127 -24
- package/dist/src/cluster/block-transfer.js.map +1 -1
- package/dist/src/cluster/certified-claims.d.ts +170 -0
- package/dist/src/cluster/certified-claims.d.ts.map +1 -0
- package/dist/src/cluster/certified-claims.js +200 -0
- package/dist/src/cluster/certified-claims.js.map +1 -0
- package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
- package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
- package/dist/src/cluster/client-signature-verifier.js +33 -0
- package/dist/src/cluster/client-signature-verifier.js.map +1 -0
- package/dist/src/cluster/cluster-policy.d.ts +9 -3
- package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
- package/dist/src/cluster/cluster-policy.js +111 -27
- package/dist/src/cluster/cluster-policy.js.map +1 -1
- package/dist/src/cluster/cluster-repo.d.ts +140 -11
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +485 -29
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-proof.d.ts +134 -0
- package/dist/src/cluster/commit-proof.d.ts.map +1 -0
- package/dist/src/cluster/commit-proof.js +263 -0
- package/dist/src/cluster/commit-proof.js.map +1 -0
- package/dist/src/cluster/quorum-restore.d.ts +95 -8
- package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
- package/dist/src/cluster/quorum-restore.js +113 -14
- package/dist/src/cluster/quorum-restore.js.map +1 -1
- package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
- package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
- package/dist/src/cluster/rebalance-monitor.js +207 -5
- package/dist/src/cluster/rebalance-monitor.js.map +1 -1
- package/dist/src/cluster/reconcile-block.d.ts +27 -7
- package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
- package/dist/src/cluster/reconcile-block.js +179 -38
- package/dist/src/cluster/reconcile-block.js.map +1 -1
- package/dist/src/cluster/service.d.ts +21 -4
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +28 -17
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +8 -2
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +7 -7
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/host.d.ts.map +1 -1
- package/dist/src/cohort-topic/host.js +8 -7
- package/dist/src/cohort-topic/host.js.map +1 -1
- package/dist/src/cohort-topic/stream-util.d.ts +7 -6
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
- package/dist/src/cohort-topic/stream-util.js +14 -41
- package/dist/src/cohort-topic/stream-util.js.map +1 -1
- package/dist/src/dispute/cascade.d.ts +7 -8
- package/dist/src/dispute/cascade.d.ts.map +1 -1
- package/dist/src/dispute/cascade.js +24 -7
- package/dist/src/dispute/cascade.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +5 -0
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +13 -3
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +33 -15
- package/dist/src/dispute/invalidation.d.ts.map +1 -1
- package/dist/src/dispute/invalidation.js +127 -34
- package/dist/src/dispute/invalidation.js.map +1 -1
- package/dist/src/dispute/service.d.ts.map +1 -1
- package/dist/src/dispute/service.js +2 -1
- package/dist/src/dispute/service.js.map +1 -1
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +78 -6
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +136 -57
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +38 -7
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +150 -62
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/logger.d.ts +2 -2
- package/dist/src/logger.js +2 -2
- package/dist/src/network/open-protocol-stream.d.ts +56 -0
- package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
- package/dist/src/network/open-protocol-stream.js +60 -0
- package/dist/src/network/open-protocol-stream.js.map +1 -0
- package/dist/src/network/register-protocol-handler.d.ts +66 -0
- package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
- package/dist/src/network/register-protocol-handler.js +51 -0
- package/dist/src/network/register-protocol-handler.js.map +1 -0
- package/dist/src/peer-address-book.d.ts +128 -1
- package/dist/src/peer-address-book.d.ts.map +1 -1
- package/dist/src/peer-address-book.js +198 -15
- package/dist/src/peer-address-book.js.map +1 -1
- package/dist/src/pend-validation.d.ts +65 -0
- package/dist/src/pend-validation.d.ts.map +1 -0
- package/dist/src/pend-validation.js +69 -0
- package/dist/src/pend-validation.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
- package/dist/src/reactivity/notify-transport.js +2 -1
- package/dist/src/reactivity/notify-transport.js.map +1 -1
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
- package/dist/src/reactivity/push-state-gossip.js +2 -1
- package/dist/src/reactivity/push-state-gossip.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +32 -6
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +44 -10
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +181 -25
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +650 -62
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/served-repo-proxy.d.ts +30 -0
- package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
- package/dist/src/repo/served-repo-proxy.js +50 -0
- package/dist/src/repo/served-repo-proxy.js.map +1 -0
- package/dist/src/repo/service.d.ts +22 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +25 -13
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/reputation/types.d.ts +3 -1
- package/dist/src/reputation/types.d.ts.map +1 -1
- package/dist/src/reputation/types.js +3 -1
- package/dist/src/reputation/types.js.map +1 -1
- package/dist/src/rn.d.ts +24 -2
- package/dist/src/rn.d.ts.map +1 -1
- package/dist/src/rn.js +33 -4
- package/dist/src/rn.js.map +1 -1
- package/dist/src/routing/libp2p-known-peers.d.ts.map +1 -1
- package/dist/src/routing/libp2p-known-peers.js +5 -0
- package/dist/src/routing/libp2p-known-peers.js.map +1 -1
- package/dist/src/storage/block-archive.d.ts +153 -0
- package/dist/src/storage/block-archive.d.ts.map +1 -0
- package/dist/src/storage/block-archive.js +194 -0
- package/dist/src/storage/block-archive.js.map +1 -0
- package/dist/src/storage/block-latch.d.ts +92 -0
- package/dist/src/storage/block-latch.d.ts.map +1 -0
- package/dist/src/storage/block-latch.js +132 -0
- package/dist/src/storage/block-latch.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +169 -12
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +415 -152
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/cached-raw-storage.d.ts +5 -1
- package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/cached-raw-storage.js +16 -1
- package/dist/src/storage/cached-raw-storage.js.map +1 -1
- package/dist/src/storage/cached-store-driver.d.ts +14 -4
- package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
- package/dist/src/storage/cached-store-driver.js +39 -5
- package/dist/src/storage/cached-store-driver.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +70 -19
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/i-block-storage.js +21 -1
- package/dist/src/storage/i-block-storage.js.map +1 -1
- package/dist/src/storage/i-raw-storage.d.ts +38 -0
- package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.d.ts +14 -8
- package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.js +29 -9
- package/dist/src/storage/kv-raw-storage.js.map +1 -1
- package/dist/src/storage/memory-store-driver.d.ts +4 -1
- package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
- package/dist/src/storage/memory-store-driver.js +22 -2
- package/dist/src/storage/memory-store-driver.js.map +1 -1
- package/dist/src/storage/raw-store-codec.js +2 -2
- package/dist/src/storage/raw-store-driver.d.ts +44 -3
- package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.d.ts +60 -3
- package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.js +68 -4
- package/dist/src/storage/shared-cache-pool.js.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +204 -26
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +422 -119
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/storage/store-identity.d.ts +21 -0
- package/dist/src/storage/store-identity.d.ts.map +1 -0
- package/dist/src/storage/store-identity.js +33 -0
- package/dist/src/storage/store-identity.js.map +1 -0
- package/dist/src/storage/struct.d.ts +15 -0
- package/dist/src/storage/struct.d.ts.map +1 -1
- package/dist/src/storage/with-read-cache.d.ts +92 -0
- package/dist/src/storage/with-read-cache.d.ts.map +1 -0
- package/dist/src/storage/with-read-cache.js +132 -0
- package/dist/src/storage/with-read-cache.js.map +1 -0
- package/dist/src/sync/service.d.ts +13 -3
- package/dist/src/sync/service.d.ts.map +1 -1
- package/dist/src/sync/service.js +7 -30
- package/dist/src/sync/service.js.map +1 -1
- package/dist/src/testing/mesh-harness.d.ts +75 -2
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +193 -81
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
- package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
- package/dist/src/testing/raw-storage-conformance.js +97 -2
- package/dist/src/testing/raw-storage-conformance.js.map +1 -1
- package/package.json +5 -6
- package/src/cluster/block-transfer-service.ts +528 -312
- package/src/cluster/block-transfer.ts +547 -424
- package/src/cluster/certified-claims.ts +319 -0
- package/src/cluster/client-signature-verifier.ts +34 -0
- package/src/cluster/cluster-policy.ts +294 -203
- package/src/cluster/cluster-repo.ts +2501 -2034
- package/src/cluster/commit-proof.ts +344 -0
- package/src/cluster/quorum-restore.ts +348 -223
- package/src/cluster/rebalance-monitor.ts +539 -254
- package/src/cluster/reconcile-block.ts +404 -203
- package/src/cluster/service.ts +308 -293
- package/src/cluster/spread-on-churn.ts +352 -346
- package/src/cohort-topic/host.ts +8 -7
- package/src/cohort-topic/stream-util.ts +14 -43
- package/src/dispute/cascade.ts +31 -15
- package/src/dispute/dispute-service.ts +706 -696
- package/src/dispute/invalidation.ts +162 -52
- package/src/dispute/service.ts +126 -125
- package/src/index.ts +7 -0
- package/src/libp2p-key-network.ts +142 -58
- package/src/libp2p-node-base.ts +1793 -1675
- package/src/logger.ts +27 -27
- package/src/network/open-protocol-stream.ts +87 -0
- package/src/network/register-protocol-handler.ts +85 -0
- package/src/peer-address-book.ts +360 -149
- package/src/pend-validation.ts +89 -0
- package/src/reactivity/notify-transport.ts +145 -144
- package/src/reactivity/push-state-gossip.ts +292 -291
- package/src/repo/cluster-coordinator.ts +65 -11
- package/src/repo/coordinator-repo.ts +729 -71
- package/src/repo/served-repo-proxy.ts +55 -0
- package/src/repo/service.ts +332 -313
- package/src/reputation/types.ts +3 -1
- package/src/rn.ts +34 -4
- package/src/routing/libp2p-known-peers.ts +31 -26
- package/src/storage/block-archive.ts +242 -0
- package/src/storage/block-latch.ts +144 -0
- package/src/storage/block-storage.ts +787 -498
- package/src/storage/cached-raw-storage.ts +21 -1
- package/src/storage/cached-store-driver.ts +898 -859
- package/src/storage/i-block-storage.ts +172 -116
- package/src/storage/i-raw-storage.ts +40 -0
- package/src/storage/kv-raw-storage.ts +34 -9
- package/src/storage/memory-store-driver.ts +26 -2
- package/src/storage/raw-store-codec.ts +42 -42
- package/src/storage/raw-store-driver.ts +45 -3
- package/src/storage/shared-cache-pool.ts +516 -452
- package/src/storage/storage-repo.ts +1421 -1014
- package/src/storage/store-identity.ts +41 -0
- package/src/storage/struct.ts +52 -34
- package/src/storage/with-read-cache.ts +182 -0
- package/src/sync/service.ts +178 -198
- package/src/testing/cohort-topic-mesh-harness.ts +673 -673
- package/src/testing/mesh-harness.ts +524 -344
- package/src/testing/raw-storage-conformance.ts +114 -2
package/src/logger.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import debug from 'debug'
|
|
2
|
-
|
|
3
|
-
const BASE_NAMESPACE = 'optimystic:db-p2p'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Build a `debug` logger under `optimystic:db-p2p:<subNamespace>`, optionally suffixed with the
|
|
7
|
-
* owning node's peer id (`:<first 12 chars>`) so lines from several nodes sharing one process —
|
|
8
|
-
* every integration test — are attributable. Omit `peerId` and the namespace is byte-for-byte the
|
|
9
|
-
* un-suffixed one, so callers that don't know their peer id are unaffected.
|
|
10
|
-
*
|
|
11
|
-
* NOTE: 12 chars matches the truncation the rest of this package already uses in log payloads, but
|
|
12
|
-
* every Ed25519 peer id starts with the constant `12D3KooW`, so only ~4 base58 characters actually
|
|
13
|
-
* distinguish nodes (~11M combinations — ample for the handful of nodes a test process runs).
|
|
14
|
-
* Widen this only if a run ever needs to match a namespace against a full peer id.
|
|
15
|
-
*
|
|
16
|
-
* NOTE: only
|
|
17
|
-
*
|
|
18
|
-
* still log under a flat namespace. Thread a peer id through any of them if a future diagnosis
|
|
19
|
-
* needs per-node attribution from that subsystem — the mechanism is already here.
|
|
20
|
-
*/
|
|
21
|
-
export function createLogger(subNamespace: string, peerId?: string): debug.Debugger {
|
|
22
|
-
const suffix = peerId ? `:${peerId.substring(0, 12)}` : ''
|
|
23
|
-
return debug(`${BASE_NAMESPACE}:${subNamespace}${suffix}`)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const verbose = typeof process !== 'undefined'
|
|
27
|
-
&& (process.env.OPTIMYSTIC_VERBOSE === '1' || process.env.OPTIMYSTIC_VERBOSE === 'true');
|
|
1
|
+
import debug from 'debug'
|
|
2
|
+
|
|
3
|
+
const BASE_NAMESPACE = 'optimystic:db-p2p'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Build a `debug` logger under `optimystic:db-p2p:<subNamespace>`, optionally suffixed with the
|
|
7
|
+
* owning node's peer id (`:<first 12 chars>`) so lines from several nodes sharing one process —
|
|
8
|
+
* every integration test — are attributable. Omit `peerId` and the namespace is byte-for-byte the
|
|
9
|
+
* un-suffixed one, so callers that don't know their peer id are unaffected.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: 12 chars matches the truncation the rest of this package already uses in log payloads, but
|
|
12
|
+
* every Ed25519 peer id starts with the constant `12D3KooW`, so only ~4 base58 characters actually
|
|
13
|
+
* distinguish nodes (~11M combinations — ample for the handful of nodes a test process runs).
|
|
14
|
+
* Widen this only if a run ever needs to match a namespace against a full peer id.
|
|
15
|
+
*
|
|
16
|
+
* NOTE: only a few call sites pass a peer id today (`Libp2pKeyPeerNetwork`, `CoordinatorRepo`, and
|
|
17
|
+
* the three `peer-address-book` sinks); the package's other ~30 `createLogger` call sites
|
|
18
|
+
* still log under a flat namespace. Thread a peer id through any of them if a future diagnosis
|
|
19
|
+
* needs per-node attribution from that subsystem — the mechanism is already here.
|
|
20
|
+
*/
|
|
21
|
+
export function createLogger(subNamespace: string, peerId?: string): debug.Debugger {
|
|
22
|
+
const suffix = peerId ? `:${peerId.substring(0, 12)}` : ''
|
|
23
|
+
return debug(`${BASE_NAMESPACE}:${subNamespace}${suffix}`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const verbose = typeof process !== 'undefined'
|
|
27
|
+
&& (process.env.OPTIMYSTIC_VERBOSE === '1' || process.env.OPTIMYSTIC_VERBOSE === 'true');
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single place in `db-p2p` that opens a libp2p protocol stream.
|
|
3
|
+
*
|
|
4
|
+
* libp2p refuses to open a protocol stream over a *limited* (circuit-relay) connection unless the
|
|
5
|
+
* caller opts in with `runOnLimitedConnection: true`. Omitting it produces no compile error and no
|
|
6
|
+
* obvious failure — only "that peer never answers" — so every peer reachable only through a relay
|
|
7
|
+
* (the steady state for browsers, phones, and NATed peers) silently drops out. The flag is
|
|
8
|
+
* deliberately NOT an option here: a new call site gets relay support without its author needing to
|
|
9
|
+
* know the flag exists, and `test/dial-options-single-site.spec.ts` fails the build if a second
|
|
10
|
+
* source file calls `dialProtocol` / `newStream` directly.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: accepted tradeoff — this duplicates FRET's `rpc/protocols.ts#openRpcStream` (exported since
|
|
13
|
+
* `p2p-fret@1.0.0-beta.3`) rather than delegating to it. FRET's helper pins `negotiateFully: false`
|
|
14
|
+
* with no way to opt out, and `cohort-topic/stream-util.ts` deliberately does not set that option
|
|
15
|
+
* (see the NOTE at its call sites); adopting FRET's would silently reverse a decision a human
|
|
16
|
+
* already made. It also has no hook for the pre-dial check `libp2p-key-network.ts#connect` runs.
|
|
17
|
+
* Revisit — and delete this module in favour of `openRpcStream` — if FRET ever parameterizes
|
|
18
|
+
* `negotiateFully`.
|
|
19
|
+
*
|
|
20
|
+
* Imports here are type-only on purpose: this module is reachable from the react-native entry
|
|
21
|
+
* (`src/rn.ts`) via `libp2p-key-network.ts`, which must not pull node-specific code.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import type { Libp2p } from "libp2p";
|
|
25
|
+
import type { Connection, PeerId, Stream } from "@libp2p/interface";
|
|
26
|
+
|
|
27
|
+
export interface OpenProtocolStreamOptions {
|
|
28
|
+
/** Forwarded to libp2p so a caller's deadline cancels both the connection reuse and the dial. */
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
/**
|
|
31
|
+
* Omit for libp2p's default (full multistream-select negotiation at stream-open).
|
|
32
|
+
* Pass `false` to save the round trip, accepting that an unsupported-protocol failure is
|
|
33
|
+
* deferred to the first read — only safe when the caller always reads a reply.
|
|
34
|
+
*/
|
|
35
|
+
negotiateFully?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Runs immediately before a FRESH dial, and never on the connection-reuse path.
|
|
38
|
+
* Throwing aborts the open. This is the seam for checks that are only meaningful when no
|
|
39
|
+
* connection exists yet (see `libp2p-key-network.ts#assertNotSelfRelayOnly`).
|
|
40
|
+
*/
|
|
41
|
+
beforeDial?: () => Promise<void> | void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* True for a circuit-relay ("limited") connection: libp2p stamps one with per-circuit `limits`
|
|
46
|
+
* (data/duration caps); sniffing `/p2p-circuit` in the remote multiaddr covers transports and
|
|
47
|
+
* versions that leave `limits` unpopulated.
|
|
48
|
+
*/
|
|
49
|
+
export function isLimitedConnection(c: Connection): boolean {
|
|
50
|
+
if (c.limits != null) return true;
|
|
51
|
+
return c.remoteAddr?.toString?.().includes("/p2p-circuit") ?? false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Open `protocol` to `peer`, reusing a healthy existing connection when there is one.
|
|
56
|
+
*
|
|
57
|
+
* Skips connections libp2p has not yet evicted from its index but that are no longer open, and
|
|
58
|
+
* prefers a direct connection over a relayed one — a relayed connection can be reset once the
|
|
59
|
+
* relay's per-circuit cap or reservation lapses, and after DCUtR upgrades a link to direct both
|
|
60
|
+
* briefly coexist. Falls back to the relayed connection when it is the only open path.
|
|
61
|
+
*/
|
|
62
|
+
export async function openProtocolStream(
|
|
63
|
+
node: Libp2p,
|
|
64
|
+
peer: PeerId,
|
|
65
|
+
protocol: string,
|
|
66
|
+
options?: OpenProtocolStreamOptions,
|
|
67
|
+
): Promise<Stream> {
|
|
68
|
+
// Before touching connections: a caller that has already given up is owed its own reason,
|
|
69
|
+
// not whatever libp2p would report several layers down.
|
|
70
|
+
options?.signal?.throwIfAborted();
|
|
71
|
+
|
|
72
|
+
const conns = node.getConnections?.(peer) ?? [];
|
|
73
|
+
const open = conns.filter(c => c?.status === "open" && typeof c?.newStream === "function");
|
|
74
|
+
const chosen = open.find(c => !isLimitedConnection(c)) ?? open[0];
|
|
75
|
+
|
|
76
|
+
// Keys are OMITTED rather than set to `undefined` when the caller did not supply them, so
|
|
77
|
+
// libp2p applies its own defaults instead of seeing an explicit `undefined`.
|
|
78
|
+
const streamOptions = {
|
|
79
|
+
runOnLimitedConnection: true,
|
|
80
|
+
...(options?.negotiateFully !== undefined ? { negotiateFully: options.negotiateFully } : {}),
|
|
81
|
+
...(options?.signal !== undefined ? { signal: options.signal } : {}),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
if (chosen) return await chosen.newStream([protocol], streamOptions);
|
|
85
|
+
await options?.beforeDial?.();
|
|
86
|
+
return await node.dialProtocol(peer, [protocol], streamOptions);
|
|
87
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single place in `db-p2p` that registers a libp2p protocol handler.
|
|
3
|
+
*
|
|
4
|
+
* The mirror image of `./open-protocol-stream.ts`. Opening a stream over a *limited* (circuit-relay)
|
|
5
|
+
* connection needs BOTH sides to opt in, and libp2p checks each side against its own options:
|
|
6
|
+
*
|
|
7
|
+
* - the dialer's `newStream` / `dialProtocol` options (`libp2p/src/connection.ts`, outbound path), and
|
|
8
|
+
* - the options the *answering* peer passed when it registered the handler
|
|
9
|
+
* (`libp2p/src/connection.ts`, incoming path — it reads back
|
|
10
|
+
* `registrar.getHandler(protocol).options.runOnLimitedConnection`).
|
|
11
|
+
*
|
|
12
|
+
* Miss either one and libp2p throws `LimitedConnectionError`. On the answering side it does so
|
|
13
|
+
* *after* multistream-select has already acknowledged the protocol, so the dialer's stream open
|
|
14
|
+
* appears to succeed and the stream is then reset with no reply — indistinguishable, from the
|
|
15
|
+
* dialer's seat, from a peer that simply does not hold the data. Every peer reachable only through
|
|
16
|
+
* a capped relay (phones, browsers, machines behind a home router) silently drops out.
|
|
17
|
+
*
|
|
18
|
+
* `openProtocolStream` fixed the dialling half; this fixes the answering half. As there, the flag is
|
|
19
|
+
* deliberately NOT an option: a new protocol gets relay support without its author needing to know
|
|
20
|
+
* the flag exists, and `test/dial-options-single-site.spec.ts` fails the build if a second source
|
|
21
|
+
* file calls `.handle(...)` directly.
|
|
22
|
+
*
|
|
23
|
+
* Accepting the stream is necessary but not sufficient. A stock relay also caps the *whole* relayed
|
|
24
|
+
* connection — `applyDefaultLimit: true` stamps `Limit { data: 128 KiB, duration: 2 min }` on every
|
|
25
|
+
* reservation — so a relay-only peer now answers, but the circuit is reset once either cap is hit,
|
|
26
|
+
* which one cohort frame (`DEFAULT_STREAM_MAX_BYTES`, 512 KiB) can do on its own. Lifting that is
|
|
27
|
+
* the relay operator's knob, not this one: see `NodeOptions.relayServerInit` in `libp2p-node-base.ts`.
|
|
28
|
+
*
|
|
29
|
+
* Imports here are type-only on purpose: this module is reachable from the react-native entry
|
|
30
|
+
* (`src/rn.ts`), which must not pull node-specific code.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { StreamHandler, StreamHandlerOptions, StreamMiddleware } from "@libp2p/interface";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Anything that can register a libp2p protocol handler.
|
|
37
|
+
*
|
|
38
|
+
* Both shapes in this package satisfy it: a `Libp2p` node (`node.handle(...)`) and the `registrar`
|
|
39
|
+
* component the service classes are constructed with (`components.registrar.handle(...)`).
|
|
40
|
+
*/
|
|
41
|
+
export interface ProtocolRegistrar {
|
|
42
|
+
handle(protocol: string, handler: StreamHandler, options?: StreamHandlerOptions): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The per-protocol settings that legitimately vary. `runOnLimitedConnection` is absent on purpose —
|
|
47
|
+
* it is a constant of this helper, not a caller's choice.
|
|
48
|
+
*/
|
|
49
|
+
export interface RegisterProtocolHandlerOptions {
|
|
50
|
+
/** Concurrent inbound streams allowed per connection. Omit for libp2p's default (32). */
|
|
51
|
+
maxInboundStreams?: number;
|
|
52
|
+
/** Concurrent outbound streams allowed per connection. Omit for libp2p's default (64). */
|
|
53
|
+
maxOutboundStreams?: number;
|
|
54
|
+
/** Stream middleware, run around the handler. Omit for none. */
|
|
55
|
+
middleware?: StreamMiddleware[];
|
|
56
|
+
/** Replace an existing registration for this protocol instead of rejecting. */
|
|
57
|
+
force?: true;
|
|
58
|
+
/** Forwarded to libp2p so a caller's deadline cancels the registration. */
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Register `handler` for `protocol`, accepting streams over limited (relay) connections.
|
|
64
|
+
*
|
|
65
|
+
* Rejects if the registrar rejects — a duplicate protocol id, or an aborted signal. Callers that
|
|
66
|
+
* register fire-and-forget (`void registerProtocolHandler(...)`) keep that behaviour; see the NOTE
|
|
67
|
+
* in `libp2p-node-base.ts` about the reactivity handlers.
|
|
68
|
+
*/
|
|
69
|
+
export async function registerProtocolHandler(
|
|
70
|
+
target: ProtocolRegistrar,
|
|
71
|
+
protocol: string,
|
|
72
|
+
handler: StreamHandler,
|
|
73
|
+
options?: RegisterProtocolHandlerOptions,
|
|
74
|
+
): Promise<void> {
|
|
75
|
+
// Keys are OMITTED rather than set to `undefined` when the caller did not supply them, so
|
|
76
|
+
// libp2p applies its own defaults instead of seeing an explicit `undefined`.
|
|
77
|
+
await target.handle(protocol, handler, {
|
|
78
|
+
runOnLimitedConnection: true,
|
|
79
|
+
...(options?.maxInboundStreams !== undefined ? { maxInboundStreams: options.maxInboundStreams } : {}),
|
|
80
|
+
...(options?.maxOutboundStreams !== undefined ? { maxOutboundStreams: options.maxOutboundStreams } : {}),
|
|
81
|
+
...(options?.middleware !== undefined ? { middleware: options.middleware } : {}),
|
|
82
|
+
...(options?.force !== undefined ? { force: options.force } : {}),
|
|
83
|
+
...(options?.signal !== undefined ? { signal: options.signal } : {}),
|
|
84
|
+
});
|
|
85
|
+
}
|