Skip to content

Latest commit

 

History

History
312 lines (217 loc) · 7.77 KB

v0.28-v0.29.md

File metadata and controls

312 lines (217 loc) · 7.77 KB

Migrating to libp2p@0.29

A migration guide for refactoring your application code from libp2p v0.28.x to v0.29.0.

Table of Contents

API

Pubsub

The libp2p-gossipsub javascript implementation is now upgraded according to the Gossipsub v1.1 spec and it packs several security hardening extensions. You can read more about it in its blogpost.

We leveraged this update to rethink the pubsub interface, in order to make it easier, as well as to be consistent with the API of the routers. Moreover, the interface was also reconstructed to ease new pubsub router implementations.

Access router instance

Libp2p prior to 0.29 unnecessarily added a layer of abstraction over the pubsub routers. We now expose the pubsub router API directly and have a test suite in the interface-pubsub to guarantee routers compliance. This enables more advanced usage of the underlying router.

Before

libp2p.pubsub._pubsub.*
libp2p.pubsub._pubsub.topicValidators.set(topic, validator)

After

libp2p.pubsub.*
libp2p.pubsub.topicValidators.set(topic, validator)

Publish

Publish uses Uint8Array data instead of Buffer.

Before

const topic = 'topic'
const data = Buffer.from('data')

await libp2p.pubsub.publish(topic, data)

After

const uint8ArrayFromString from 'uint8arrays/from-string')

const topic = 'topic'
const data = uint8ArrayFromString('data')

await libp2p.pubsub.publish(topic, data)

Subscribe

Handlers should no longer be passed when subscribing, instead, applications should bind event handlers for each topic they wish to subscribe too. This enables more flexibility at the application level without changing the underlying subscriptions. Message data is now a Uint8Array instead of Buffer.

Before

const topic = 'topic'
const handler = (msg) => {
  // msg.data - pubsub data received
  const data = msg.data.toString()
}
libp2p.pubsub.subscribe(topic, handler)

After

const uint8ArrayToString from 'uint8arrays/to-string')

const topic = 'topic'
const handler = (msg) => {
  // msg.data - pubsub data received
  const data = uint8ArrayToString(msg.data)
}
libp2p.pubsub.on(topic, handler)
libp2p.pubsub.subscribe(topic)

In the latest release, despite not being documented in libp2p the underlying pubsub routers supported subscribing to multiple topics at the same time. We removed that code complexity, since this is easily achieved in the application layer if needed.

Before

const topics = ['a', 'b']
const handler = (msg) => {
  // msg.data - pubsub data received
  const data = msg.data.toString()
}
libp2p.pubsub.subscribe(topics, handler)

After

const uint8ArrayToString from 'uint8arrays/to-string')

const topics = ['a', 'b']
const handler = (msg) => {
  // msg.data - pubsub data received
  const data = uint8ArrayToString(msg.data)
}

topics.forEach((topic) => {
  libp2p.pubsub.on(topic, handler)
  libp2p.pubsub.subscribe(topic)
})

Unsubscribe

Handlers should not be directly bound to the subscription anymore.

Before

const topic = 'topic'
const handler = (msg) => {
  // msg.data - pubsub data received
}
libp2p.pubsub.unsubscribe(topic, handler)

After

const topic = 'topic'
const handler = (msg) => {
  // msg.data - pubsub data received
}
libp2p.pubsub.removeListener(topic, handler)
libp2p.pubsub.unsubscribe(topic)

Topic Validators

The validator function does not include the peer parameter anymore. It was redundant since it is included in the message and it could lead to issues as the peer that sent the message might not be the one who created the message in first place. The validator function should also throw an error instead of returning false when the message is not valid.

Before

const validator = (msgTopic, peer, msg) => {
  // process message
  return false
}
libp2p.pubsub._pubsub.topicValidators.set(topic, validator)

After

const validator = (msgTopic, msg) => {
  const from = msg.from
  // process message
  throw new Error('not a valid message')
}
libp2p.pubsub.topicValidators.set(topic, validator)

Uint8Arrays replace node Buffers

Aiming to improve libp2p browser support, we are moving away from node core modules unless we can guarantee that the code we are writing will not run in a browser. It is worth mentioning that modern JavaScript runtimes have TypedArrays such as Uint8Array backed by ArrayBuffers. All libp2p dependencies were also updated to use Uint8Array.

We use the uint8arrays utilities module to deal with Uint8Arrays easily and we recommend its usage in the application layer. Thanks for the module @achingbrain! It includes utilities like compare, concat, equals, fromString and toString. In this migration examples, we will be using the following:

const uint8ArrayFromString from 'uint8arrays/from-string')
const uint8ArrayToString from 'uint8arrays/to-string')

contentRouting.put

Before

const key = '/key'
const value = Buffer.from('oh hello there')

await libp2p.contentRouting.put(key, value)

After

const key = '/key'
const value = uint8ArrayFromString('oh hello there')

await libp2p.contentRouting.put(key, value)

contentRouting.get

Before

const key = '/key'
const value = await libp2p.contentRouting.put(key)

console.log('store value is: ', value.toString())

After

const key = '/key'
const value = await libp2p.contentRouting.put(key)

console.log('store value is: ', uint8ArrayToString(value))

metadataBook.set

Before

peerStore.metadataBook.set(peerId, 'location', Buffer.from('Saturn'))

After

peerStore.metadataBook.set(peerId, 'location', uint8ArrayFromString('Saturn'))

metadataBook.get

Before

const data = peerStore.metadataBook.get(peerId)

console.log('stored location: ', data.get('location').toString())

After

const data = peerStore.metadataBook.get(peerId)

console.log('stored location: ', uint8ArrayToString(data.get('location')))

metadataBook.getValue

Before

const location = peerStore.metadataBook.getValue(peerId, 'location')

console.log('stored location: ', location.toString())

After

const location = peerStore.metadataBook.getValue(peerId, 'location')

console.log('stored location: ', uint8ArrayToString(location))

keychain.cms.encrypt

Before

const keyInfo = await libp2p.keychain.createKey('keyTest', 'rsa', 4096)
const enc = await libp2p.keychain.cms.encrypt('keyTest', Buffer.from('data'))

After

const keyInfo = await libp2p.keychain.createKey('keyTest', 'rsa', 4096)
const enc = await libp2p.keychain.cms.encrypt('keyTest', uint8ArrayFromString('data'))

pubsub

Already specified in its own chapter above.

Module Updates

With this release you should update the following libp2p modules if you are relying on them:

"libp2p-bootstrap": "^0.12.0",
"libp2p-delegated-content-routing": "^0.6.0",
"libp2p-delegated-peer-routing": "^0.6.0",
"libp2p-floodsub": "^0.23.0",
"libp2p-gossipsub": "^0.6.0",
"libp2p-kad-dht": "^0.20.0",
"libp2p-mdns": "^0.15.0",
"libp2p-mplex": "^0.10.0",
"libp2p-noise": "^2.0.0",
"libp2p-secio": "^0.13.1",
"libp2p-tcp": "^0.15.1",
"libp2p-webrtc-star": "^0.20.0",
"libp2p-websockets": "^0.14.0",