P2P Docs
ReferenceHelpers

blind-peering

Client that asks blind peers to keep Hypercores and Autobases available and to forward push notifications.

Documented against v2.10.1
stable

blind-peering is the client half of blind peering. It connects your app to one or more blind peers—always-on servers that replicate and store Hypercores without being able to read them—and asks them to keep the cores and Autobases you register available when no writer is online. It can also ask a blind peer to forward a push notification about a new block. For upstream source and releases, see the blind-peering repository.

Install

npm i blind-peering

Quickstart

import Hyperswarm from 'hyperswarm'
import Corestore from 'corestore'
import BlindPeering from 'blind-peering'

const swarm = new Hyperswarm()
const store = new Corestore('./app-storage')
swarm.on('connection', (conn) => store.replicate(conn))

const core = store.get({ name: 'messages' })
await core.append('hello')

const blind = new BlindPeering(swarm.dht, store.namespace('blind-peering'), {
  blindPeers: [{ key: '<blind peer public key, hex or z32>' }]
})

// Resolves once the connection to each picked blind peer is open
await blind.addCore(core)

await blind.close()
await swarm.destroy()
await store.close()

Run the server side with pear blind-peer start or embed one with blind-peer. The server prints the public key you pass in blindPeers.

API Reference

Constructor and lifecycle

new BlindPeering(dht, store[, opts])

src

Create a client. It connects to a blind peer only when a core, an autobase or a notification needs one.

ParameterTypeDefaultDescription
dhtHyperDHT—The DHT node used to connect to blind peers, usually swarm.dht. The client reconnects when it emits network-change.
storeCorestore—The store that holds the cores you register. The client replicates it over every blind-peer connection. A namespace such as store.namespace('blind-peering') works.
optsBlindPeeringOptions{}Client options.
  • Throws: if a key in blindPeers or keys isn't a 32-byte key or a hyperdht-address encoding of one. For example Invalid Hypercore key.
const blind = new BlindPeering(swarm.dht, store.namespace('blind-peering'), {
  blindPeers: [{ key: blindPeerKey }]
})

await blind.close()

src

Close the client. It closes every blind-peer connection, stops reconnecting and drops all registrations. A pending addCore() or addAutobase() call settles when the client closes.

Close the client before the swarm and store it uses.

await blind.suspend()

src

Close every blind-peer connection and stop reconnecting. Registrations stay in place. Use it when your app goes to the background and shouldn't hold connections open.

While the client is suspended, addCore() and addAutobase() record the registration and resolve at once. The request goes out on resume().

await blind.resume()

src

Reconnect after suspend() and send every registration again. Clients created with the suspended option start in this state, so call resume() to begin.

Properties

blind.keys

src

The public keys of the configured blind peers.

blind.suspended / blind.closed

src

true while the client is suspended / once close() has been called.

  • Returns: boolean

blind.stats

src

Counters since the client was created.

  • Returns: { addCore, addAutobase, addCoresTx, notificationsTx }
CounterCounts
addCoreCore registrations sent to blind peers: one per core per blind peer, counted again when a core has grown.
addAutobaseAutobase registrations: one per autobase per blind peer.
addCoresTxadd-cores requests sent to blind peers. An autobase sends several.
notificationsTxNotifications sent to a blind peer.

Blind peers

blind.setBlindPeers(blindPeers)

src

Replace the configured blind peers and register every core and autobase you already added with the new set.

ParameterTypeDescription
blindPeersArray<BlindPeerInfo>The new list.
  • Throws: if a key is invalid, as the constructor does.

blind.setKeys(keys)

src

Same as setBlindPeers() for a list of keys without groups. The keys constructor option is the matching form.

ParameterTypeDescription
keysArray<Buffer|string>Blind peer public keys.

blind.bump()

src

Reset the reconnect backoff of every blind-peer connection and retry now. The client calls it when the DHT emits network-change.

Keeping data available

await blind.addCore(core[, opts])

src

Ask blind peers to keep a Hypercore. Each picked blind peer replicates the core, stores it and serves it to other peers.

ParameterTypeDescription
coreHypercoreThe core to register. It's opened first if needed.
optsAddCoreOptionsRegistration options.
  • Returns: Promise<void>—resolves once the connection to each picked blind peer is open.

If a picked blind peer is unreachable, the client retries with backoff and the promise stays pending until it connects or the client closes. The promise resolves without registering anything when the core is closing. Closing a registered core removes its registration.

Calling addCore() again for the same core keeps the options of the first call. The client sends a new request only when the core has grown and the blind peer isn't already replicating it.

await blind.addCore(core, { priority: 1, pick: 3 })

blind.addCoreBackground(core[, opts])

src

Same as addCore(), but returns at once and doesn't report failures.

  • Returns: void

await blind.addAutobase(base[, opts])

src

Ask blind peers to keep an Autobase: its view cores and its writer cores. An Autobee works too, since 2.9.0.

ParameterTypeDescription
baseAutobase|AutobeeThe autobase to register. It's opened first if needed.
optsAddCoreOptionsSame options as addCore(), with the defaults noted there.
  • Returns: Promise<void>—resolves once the connection to each picked blind peer is open.

The client sends the autobase's view cores in one request, and your local writer core plus a sample of the other writer cores in another. The sample is sized by maxBatchMin and maxBatchMax. Writers the autobase discovers afterwards go out once more, after batchIdleWait milliseconds without a new writer and at most batchMaxWait milliseconds after the call. The client doesn't send writers added after that again. It finds every view and writer core through the autobase itself, so the additionalViews option that earlier releases accepted is ignored since 2.9.0. Register cores that aren't part of the autobase with addCore().

await blind.addAutobase(base)

blind.addAutobaseBackground(base[, opts])

src

Same as addAutobase(), but returns at once and doesn't report failures.

  • Returns: void

Push notifications

await blind.sendNotification(core[, opts])

src

Ask a blind peer to build a blind-push notification for a block of core and forward it to its push gateway. The blind peer needs the core already registered, and needs push gateways configured with pushGatewayKeys. Without a gateway it accepts the request and drops it.

ParameterTypeDescription
coreHypercoreThe core that has the new block.
optsSendNotificationOptionsNotification options.
  • Returns: Promise<void>—resolves once a blind peer has accepted the request.
  • Throws: Timed out if the call can't get a rate-limit token within notificationRateLimit.timeout. No peers available if none of the picked blind peers could be reached or accepted the request. A failure from a blind peer that is already connected is thrown as is.

The client picks among the pick blind peers closest to target. It prefers a random one that is already connected. If none is connected it tries them in order, waiting up to 5 seconds for each connection. Before 2.9.1 it used the single closest connected blind peer. The call is rate limited by notificationRateLimit.

await blind.sendNotification(core, { appId: 'my-app' })

blind.sendNotificationBackground(core[, opts])

src

Same as sendNotification(), but returns at once and doesn't report failures.

  • Returns: void

Types

BlindPeeringOptions

Options for the BlindPeering constructor.

PropertyTypeDefaultDescription
blindPeersArray<BlindPeerInfo>[]The blind peers to use. Always set it, because with none the client has nobody to contact.
keysArray<Buffer|string>[]Older form of blindPeers: keys without groups. Used only when blindPeers is empty.
picknumber2How many blind peers each core or autobase registers with, and how many of the closest peers sendNotification() chooses among.
wakeupobjectnullA protomux-wakeup instance, such as an Autobase's wakeupProtocol. The client adds every blind-peer connection to it, so the blind peer can wake your peers.
suspendedbooleanfalseStart suspended. Call resume() to connect.
relayThroughBuffer|Array<Buffer>|functionnullPassed to dht.connect() as relayThrough for every blind-peer connection.
client{ name, version }nullIdentifies your app to blind peers. Both values go in the connection handshake. Added in 2.10.0.
skipConnectionMetadatabooleanfalseWhen true, the handshake carries no metadata: neither client nor the blind-peering version. Added in 2.10.1.
notificationRateLimit{ capacity, interval, timeout }{ capacity: 10, interval: 1000, timeout: 10000 }Limit on sendNotification(): bursts of up to capacity calls, then one more call every interval milliseconds. A call waits at most timeout milliseconds for its turn. Pass null to turn the limit off.
gcWaitnumber2000Milliseconds between checks for idle blind-peer connections. A connection closes once every core and autobase registered through it has closed and uploads to it have been quiet for a few checks.
maxBatchMinnumber3How many writer cores an autobase request includes before the client starts sampling. Static cores, and cores whose first block no peer has acknowledged, are always included.
maxBatchMaxnumber9The most writer cores the client adds by sampling to an autobase request. It samples at random, and prefers cores that no peer has fully acknowledged.
batchIdleWaitnumber2000Milliseconds after the last newly found writer before the follow-up autobase request goes out.
batchMaxWaitnumber10000Most milliseconds the follow-up autobase request waits.
backoffResetWaitnumber10000Milliseconds a connection has to stay up before its reconnect backoff resets. The backoff grows from 0 to 60 seconds.

BlindPeerInfo

One blind peer.

PropertyTypeDescription
keyBuffer|stringThe blind peer's public key: 32 bytes, or a hex or z32 string. A hyperdht-address encoding is also accepted: the key plus DHT node addresses that HyperDHT uses as relay addresses for the connection.
groupstringOptional. Where the blind peer is hosted. When the client picks several peers for one core, it takes them from different groups where it can.

AddCoreOptions

Options for addCore() and addAutobase().

PropertyTypeDefaultDescription
targetBuffercore.key. For an autobase, base.wakeupCapability.key.The key the client measures XOR distance to when it picks blind peers. The default spreads cores across the configured peers. Set it to a blind peer's public key to use that peer.
picknumberThe client's pickHow many blind peers to register with.
prioritynumber0 for a core, 1 for an autobaseHow long the blind peer should hold on to the data: 0 low, 1 normal, 2 high. See priority.
announcebooleanfalseAsk the blind peer to announce the core on the swarm. Only trusted peers get this. For anyone else the blind peer resets it to false.
referrerBuffernull for a core. For an autobase, target.A key the blind peer files the core under. It uses the key to wake peers that follow it when the core changes.
blindPeersArray<BlindPeerInfo>The client's listRegister with these blind peers instead of the configured ones.
keysArray<Buffer|string>—Older form of blindPeers.

For an autobase, the writer cores carry the referrer. The view cores carry none.

SendNotificationOptions

Options for sendNotification().

PropertyTypeDefaultDescription
roomKeyBuffercore.keyThe key that encrypts the notification. A receiver needs it to read the notification.
roomDiscoveryKeyBufferThe discovery key of roomKeyThe room's discovery key, exposed in the notification.
indexnumbercore.length - 1The index of the block the notification proves.
targetBuffercore.keyThe key the client measures XOR distance to when it picks blind peers.
extraBuffernullMetadata embedded in the encrypted notification.
appIdstringnullIdentifies your app to the push gateway.
blindPeersArray<BlindPeerInfo>The client's listUse these blind peers instead of the configured ones.
keysArray<Buffer|string>—Older form of blindPeers.

See also

Last updated on

Was this helpful?

On this page