Skip to content

Commit

Permalink
fix: add a test for reading the peer id from the datastore (#397)
Browse files Browse the repository at this point in the history
Adds a test to ensure that the peer id is stable when reusing the
same datastore.
  • Loading branch information
achingbrain authored Jan 19, 2024
1 parent 031519c commit 4836d52
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 29 deletions.
25 changes: 17 additions & 8 deletions packages/helia/src/utils/libp2p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createLibp2p as create } from 'libp2p'
import { libp2pDefaults } from './libp2p-defaults.js'
import type { DefaultLibp2pServices } from './libp2p-defaults.js'
import type { ComponentLogger, Libp2p, PeerId } from '@libp2p/interface'
import type { KeychainInit } from '@libp2p/keychain'
import type { Keychain, KeychainInit } from '@libp2p/keychain'
import type { Datastore } from 'interface-datastore'
import type { Libp2pOptions } from 'libp2p'

Expand All @@ -23,31 +23,40 @@ export interface Libp2pDefaultsOptions {
}

export async function createLibp2p <T extends Record<string, unknown> = DefaultLibp2pServices> (options: CreateLibp2pOptions<T>): Promise<Libp2p<T>> {
let peerId = options.libp2p?.peerId
const peerId = options.libp2p?.peerId
const logger = options.logger ?? defaultLogger()
const selfKey = new Key('/pkcs8/self')
let chain: Keychain | undefined

// if no peer id was passed, try to load it from the keychain
if (peerId == null) {
const chain = keychain(options.keychain)({
if (peerId == null && options.datastore != null) {
chain = keychain(options.keychain)({
datastore: options.datastore,
logger
})

const selfKey = new Key('/pkcs8/self')

if (await options.datastore.has(selfKey)) {
// load the peer id from the keychain
peerId = await chain.exportPeerId('self')
options.libp2p = options.libp2p ?? {}
options.libp2p.peerId = await chain.exportPeerId('self')
}
}

const defaults = libp2pDefaults(options)
defaults.datastore = defaults.datastore ?? options.datastore
options = options ?? {}

// @ts-expect-error derived ServiceMap is not compatible with ServiceFactoryMap
return create({
const node = await create({
...defaults,
...options.libp2p,
start: false
})

if (peerId == null && chain != null && !await options.datastore.has(selfKey)) {
// persist the peer id in the keychain for next time
await chain.importPeer('self', node.peerId)
}

return node
}
35 changes: 14 additions & 21 deletions packages/helia/test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
/* eslint-env mocha */
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { webSockets } from '@libp2p/websockets'
import { expect } from 'aegir/chai'
import { MemoryBlockstore } from 'blockstore-core'
import { MemoryDatastore } from 'datastore-core'
import { createLibp2p } from 'libp2p'
import { createHelia, type HeliaLibp2p } from '../src/index.js'

describe('helia', () => {
let helia: HeliaLibp2p<any>

beforeEach(async () => {
helia = await createHelia({
datastore: new MemoryDatastore(),
blockstore: new MemoryBlockstore(),
libp2p: await createLibp2p({
transports: [
webSockets()
],
connectionEncryption: [
noise()
],
streamMuxers: [
yamux()
]
})
})
helia = await createHelia()
})

afterEach(async () => {
Expand Down Expand Up @@ -54,4 +34,17 @@ describe('helia', () => {
it('should have a libp2p', async () => {
expect(helia).to.have.property('libp2p').that.is.ok()
})

it('should have the same peer id after a restart', async () => {
const datastore = helia.datastore
const peerId = helia.libp2p.peerId

await helia.stop()

helia = await createHelia({
datastore
})

expect(helia.libp2p.peerId.toString()).to.equal(peerId.toString())
})
})

0 comments on commit 4836d52

Please sign in to comment.