Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

fix!: remove @libp2p/components #144

Merged
merged 2 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,20 @@
"release": "aegir release"
},
"dependencies": {
"@libp2p/components": "^3.0.0",
"@libp2p/interface-peer-discovery": "^1.0.1",
"@libp2p/interface-peer-info": "^1.0.3",
"@libp2p/interface-peer-store": "^1.2.2",
"@libp2p/interfaces": "^3.0.3",
"@libp2p/logger": "^2.0.1",
"@libp2p/peer-id": "^1.1.15",
"@multiformats/mafmt": "^11.0.3",
"@multiformats/multiaddr": "^11.0.0"
},
"devDependencies": {
"@libp2p/interface-peer-discovery-compliance-tests": "^1.0.2",
"@libp2p/interface-peer-discovery-compliance-tests": "^2.0.0",
"@libp2p/interface-peer-id": "^1.0.4",
"@libp2p/peer-store": "^4.0.0",
"@libp2p/peer-id-factory": "^1.0.18",
"@libp2p/peer-store": "^5.0.0",
"aegir": "^37.5.3",
"datastore-core": "^8.0.1",
"delay": "^5.0.0"
Expand Down
28 changes: 17 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface-peer-
import type { PeerInfo } from '@libp2p/interface-peer-info'
import { peerIdFromString } from '@libp2p/peer-id'
import { symbol } from '@libp2p/interface-peer-discovery'
import { Components, Initializable } from '@libp2p/components'
import type { Startable } from '@libp2p/interfaces/dist/src/startable'
import type { PeerStore } from '@libp2p/interface-peer-store'

const log = logger('libp2p:bootstrap')

Expand All @@ -15,7 +16,7 @@ const DEFAULT_BOOTSTRAP_TAG_VALUE = 50
const DEFAULT_BOOTSTRAP_TAG_TTL = 120000
const DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT = 1000

export interface BootstrapOptions {
export interface BootstrapInit {
/**
* The list of peer addresses in multi-address format
*/
Expand All @@ -42,24 +43,29 @@ export interface BootstrapOptions {
tagTTL?: number
}

export interface BootstrapComponents {
peerStore: PeerStore
}

/**
* Emits 'peer' events on a regular interval for each peer in the provided list.
*/
export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
static tag = 'bootstrap'

private timer?: ReturnType<typeof setTimeout>
private readonly list: PeerInfo[]
private readonly timeout: number
private components: Components = new Components()
private readonly _init: BootstrapOptions
private readonly components: BootstrapComponents
private readonly _init: BootstrapInit

constructor (options: BootstrapOptions = { list: [] }) {
constructor (components: BootstrapComponents, options: BootstrapInit = { list: [] }) {
if (options.list == null || options.list.length === 0) {
throw new Error('Bootstrap requires a list of peer addresses')
}
super()

this.components = components
this.timeout = options.timeout ?? DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT
this.list = []

Expand Down Expand Up @@ -89,10 +95,6 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
this._init = options
}

init (components: Components) {
this.components = components
}

get [symbol] (): true {
return true
}
Expand Down Expand Up @@ -131,7 +133,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
}

for (const peerData of this.list) {
await this.components.getPeerStore().tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
await this.components.peerStore.tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
value: this._init.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
ttl: this._init.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
})
Expand All @@ -156,3 +158,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
this.timer = undefined
}
}

export function bootstrap (init: BootstrapInit): (components: BootstrapComponents) => PeerDiscovery {
return (components: BootstrapComponents) => new Bootstrap(components, init)
}
58 changes: 27 additions & 31 deletions test/bootstrap.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,50 @@

import { expect } from 'aegir/chai'
import { IPFS } from '@multiformats/mafmt'
import { Bootstrap } from '../src/index.js'
import { bootstrap, BootstrapComponents } from '../src/index.js'
import peerList from './fixtures/default-peers.js'
import partialValidPeerList from './fixtures/some-invalid-peers.js'
import { isPeerId } from '@libp2p/interface-peer-id'
import { Components } from '@libp2p/components'
import { PersistentPeerStore } from '@libp2p/peer-store'
import { MemoryDatastore } from 'datastore-core'
import { multiaddr } from '@multiformats/multiaddr'
import { peerIdFromString } from '@libp2p/peer-id'
import delay from 'delay'
import { start, stop } from '@libp2p/interfaces/startable'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'

describe('bootstrap', () => {
let components: Components
let components: BootstrapComponents

beforeEach(() => {
const datastore = new MemoryDatastore()
const peerStore = new PersistentPeerStore()

components = new Components({
peerStore,
datastore
})

peerStore.init(components)
beforeEach(async () => {
components = {
peerStore: new PersistentPeerStore({
peerId: await createEd25519PeerId(),
datastore: new MemoryDatastore()
})
}
})

it('should throw if no peer list is provided', () => {
expect(() => new Bootstrap())
// @ts-expect-error missing args
expect(() => bootstrap()())
.to.throw('Bootstrap requires a list of peer addresses')
})

it('should discover bootstrap peers', async function () {
this.timeout(5 * 1000)
const r = new Bootstrap({
const r = bootstrap({
list: peerList,
timeout: 100
})
r.init(components)
})(components)

const p = new Promise((resolve) => r.addEventListener('peer', resolve, {
once: true
}))
r.start()
await start(r)

await p
r.stop()
await stop(r)
})

it('should tag bootstrap peers', async function () {
Expand All @@ -57,19 +55,18 @@ describe('bootstrap', () => {
const tagValue = 10
const tagTTL = 50

const r = new Bootstrap({
const r = bootstrap({
list: peerList,
timeout: 100,
tagName,
tagValue,
tagTTL
})
r.init(components)
})(components)

const p = new Promise((resolve) => r.addEventListener('peer', resolve, {
once: true
}))
r.start()
await start(r)

await p

Expand All @@ -82,29 +79,28 @@ describe('bootstrap', () => {

const bootstrapper0PeerId = peerIdFromString(bootstrapper0PeerIdStr)

const tags = await components.getPeerStore().getTags(bootstrapper0PeerId)
const tags = await components.peerStore.getTags(bootstrapper0PeerId)

expect(tags).to.have.lengthOf(1, 'bootstrap tag was not set')
expect(tags).to.have.nested.property('[0].name', tagName, 'bootstrap tag had incorrect name')
expect(tags).to.have.nested.property('[0].value', tagValue, 'bootstrap tag had incorrect value')

await delay(tagTTL * 2)

const tags2 = await components.getPeerStore().getTags(bootstrapper0PeerId)
const tags2 = await components.peerStore.getTags(bootstrapper0PeerId)

expect(tags2).to.have.lengthOf(0, 'bootstrap tag did not expire')

r.stop()
await stop(r)
})

it('should not fail on malformed peers in peer list', async function () {
this.timeout(5 * 1000)

const r = new Bootstrap({
const r = bootstrap({
list: partialValidPeerList,
timeout: 100
})
r.init(components)
})(components)

const p = new Promise<void>((resolve) => {
r.addEventListener('peer', (evt) => {
Expand All @@ -118,9 +114,9 @@ describe('bootstrap', () => {
})
})

r.start()
await start(r)

await p
r.stop()
await stop(r)
})
})
24 changes: 10 additions & 14 deletions test/compliance.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
/* eslint-env mocha */

import tests from '@libp2p/interface-peer-discovery-compliance-tests'
import { Bootstrap } from '../src/index.js'
import { bootstrap } from '../src/index.js'
import peerList from './fixtures/default-peers.js'
import { Components } from '@libp2p/components'
import { PersistentPeerStore } from '@libp2p/peer-store'
import { MemoryDatastore } from 'datastore-core'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'

describe('compliance tests', () => {
tests({
async setup () {
const datastore = new MemoryDatastore()
const peerStore = new PersistentPeerStore()
const components = new Components({
peerStore,
datastore
})
peerStore.init(components)
const components = {
peerStore: new PersistentPeerStore({
peerId: await createEd25519PeerId(),
datastore: new MemoryDatastore()
})
}

const bootstrap = new Bootstrap({
return bootstrap({
list: peerList,
timeout: 100
})
bootstrap.init(components)

return bootstrap
})(components)
},
async teardown () {}
})
Expand Down