Skip to content

Latest commit

 

History

History
147 lines (108 loc) · 4.54 KB

v0.37-v0.38.md

File metadata and controls

147 lines (108 loc) · 4.54 KB

Migrating to libp2p@39

A migration guide for refactoring your application code from libp2p v0.37.x to v0.38.0.

Table of Contents

Streams

The type of streams has changed. Previously it was Duplex<Uint8Array>, now it is Duplex<Uint8ArrayList, Uint8ArrayList | Uint8Array>.

This means you will source Uint8ArrayLists and sink Uint8ArrayList | Uint8Array.

This has changed because bytes returned by stream sources are usually obtained from multiplexed streams. A single data message sent over these streams may be transmitted as multiple smaller messages, for example where the data being sent is bigger than the multiplexer's message size limit. To return a contiguous block of bytes as a Uint8Array, where the bytes were sent as multiple message this would then involve a memory copy which is expensive.

Instead the stream will now yield Uint8ArrayLists which can be backed by multiple Uint8Array or subarrays of Uint8Array which avoid the memory-copy penalty.

Either Uint8ArrayLists or Uint8Arrays can be yielded to the stream sink and they will be handled transparently.

If you require Uint8Arrays in a stream handler, you can call .subarray on the Uint8ArrayList which will return a Uint8Array of the list contents - where the list is backed by a single Uint8Array it will be returned as-is, otherwise a new Uint8Array will be created and the contents of the list's backing Uint8Arrays copied into it, which is similar to the behaviour of older libp2p versions.

Before

const stream = await libp2p.dialProtocol(peerId, protocol)

await pipe(
  stream,
  async function * (source) {
    for await (const buf of source) {
      // buf is a Uint8Array
    }
  },
  stream
)

After

const stream = await libp2p.dialProtocol(peerId, protocol)

await pipe(
  stream,
  async function * (source) {
    for await (const list of source) {
      // list is a Uint8ArrayList
      const buf = list.subarray()
      // buf is a Uint8Array, only convert if necessary to avoid copying memory
    }
  },
  stream
)

Tagging peers

[email protected] brings a new mechanism for tagging peers in the peer store with values. These values are used to select connections to close when limits are reached, and there are also some special values that trigger certain behaviour like connecting to peers on startup.

The peer tagging mechanism replaces the notion of peer values in the connection manager.

Subsystems such as kad-dht and gossipsub will tag peers important to them (KAD-close or in topic meshes, for example) to ensure connections are prioritized appropriately.

When not specified, default values will be used as defined in the registrar.

Before

libp2p.connectionManager.setPeerValue(peerId, 0.5)

After

import { KEEP_ALIVE } from '@libp2p/interface-peer-store/tags'

// this peer will be connected to on startup and also reconnected to if the connection drops
await libp2p.connectionManager.tagPeer(peerId, KEEP_ALIVE)

await libp2p.connectionManager.tagPeer(peerId, 'my-tag-value', {
  // a value 0-100
  value: 0.5,

  // an optional time in ms after which the tag will be removed
  ttl: 1000
})

Protocol stream limits

To prevent remote peers overloading nodes by opening excessive amounts of protocol streams, stream handlers can specify limits on how many streams can be open concurrently for that protocol.

Before

await libp2p.handle('/my-protocol/1.0.0', (stream) => {
  // ...handle stream
})

After

await libp2p.handle('/my-protocol/1.0.0', (stream) => {
  // ...handle stream
}, {
  // specify the maximum number of concurrent inbound streams for this protocol
  maxInboundStreams: 1,
  // specify the maximum number of concurrent outbound streams for this protocol
  maxOutboundStreams: 1
})

For built-in protocols, these can be configured using the createLibp2p factory function:

Before

const node = await createLibp2p({
  //... other options
})

After

const node = await createLibp2p({
  identify: {
    maxInboundStreams: 1,
    maxOutboundStreams: 1,
    maxPushIncomingStreams: 1,
    maxPushOutgoingStreams: 1
  },
  ping: {
    maxInboundStreams: 1,
    maxOutboundStreams: 1,
  },
  fetch: {
    maxInboundStreams: 1
    maxOutboundStreams: 1
  }
  //... other options
})