Skip to content

Commit 35f47da

Browse files
committed
fix: conform to peer schema
1 parent 814f9ef commit 35f47da

File tree

3 files changed

+77
-47
lines changed

3 files changed

+77
-47
lines changed

packages/client/src/client.ts

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import PQueue from 'p-queue'
1212
import { DelegatedRoutingV1HttpApiClientContentRouting, DelegatedRoutingV1HttpApiClientPeerRouting } from './routings.js'
1313
import type { DelegatedRoutingV1HttpApiClient, DelegatedRoutingV1HttpApiClientInit, PeerRecord } from './index.js'
1414
import type { ContentRouting, PeerRouting, AbortOptions, PeerId } from '@libp2p/interface'
15+
import type { Multiaddr } from '@multiformats/multiaddr'
1516
import type { CID } from 'multiformats'
1617

1718
const log = logger('delegated-routing-v1-http-api-client')
@@ -68,7 +69,7 @@ export class DefaultDelegatedRoutingV1HttpApiClient implements DelegatedRoutingV
6869
this.started = false
6970
}
7071

71-
async * getProviders (cid: CID, options: AbortOptions = {}): AsyncGenerator<PeerRecord, any, unknown> {
72+
async * getProviders (cid: CID, options: AbortOptions = {}): AsyncGenerator<PeerRecord> {
7273
log('getProviders starts: %c', cid)
7374

7475
const signal = anySignal([this.shutDownController.signal, options.signal, AbortSignal.timeout(this.timeout)])
@@ -109,14 +110,14 @@ export class DefaultDelegatedRoutingV1HttpApiClient implements DelegatedRoutingV
109110
const body = await res.json()
110111

111112
for (const provider of body.Providers) {
112-
const record = this.#handleProviderRecords(provider)
113+
const record = this.#conformToPeerSchema(provider)
113114
if (record != null) {
114115
yield record
115116
}
116117
}
117118
} else {
118119
for await (const provider of ndjson(toIt(res.body))) {
119-
const record = this.#handleProviderRecords(provider)
120+
const record = this.#conformToPeerSchema(provider)
120121
if (record != null) {
121122
yield record
122123
}
@@ -131,7 +132,7 @@ export class DefaultDelegatedRoutingV1HttpApiClient implements DelegatedRoutingV
131132
}
132133
}
133134

134-
async * getPeers (peerId: PeerId, options: AbortOptions | undefined = {}): AsyncGenerator<PeerRecord, any, unknown> {
135+
async * getPeers (peerId: PeerId, options: AbortOptions | undefined = {}): AsyncGenerator<PeerRecord> {
135136
log('getPeers starts: %c', peerId)
136137

137138
const signal = anySignal([this.shutDownController.signal, options.signal, AbortSignal.timeout(this.timeout)])
@@ -172,14 +173,14 @@ export class DefaultDelegatedRoutingV1HttpApiClient implements DelegatedRoutingV
172173
const body = await res.json()
173174

174175
for (const peer of body.Peers) {
175-
const record = this.#handlePeerRecords(peerId, peer)
176+
const record = this.#conformToPeerSchema(peer)
176177
if (record != null) {
177178
yield record
178179
}
179180
}
180181
} else {
181182
for await (const peer of ndjson(toIt(res.body))) {
182-
const record = this.#handlePeerRecords(peerId, peer)
183+
const record = this.#conformToPeerSchema(peer)
183184
if (record != null) {
184185
yield record
185186
}
@@ -272,44 +273,25 @@ export class DefaultDelegatedRoutingV1HttpApiClient implements DelegatedRoutingV
272273
}
273274
}
274275

275-
#handleProviderRecords (record: any): PeerRecord | undefined {
276-
if (record.Schema === 'peer') {
277-
// Peer schema can have additional, user-defined, fields.
278-
record.ID = peerIdFromString(record.ID)
279-
record.Addrs = record.Addrs?.map(multiaddr) ?? []
280-
return record
281-
}
276+
#conformToPeerSchema (record: any): PeerRecord | undefined {
277+
const protocols: string[] = []
278+
const multiaddrs: Multiaddr[] = record.Addrs?.map(multiaddr) ?? []
282279

283-
if (record.Schema === 'bitswap') {
284-
// Bitswap schema is deprecated, was incorrectly used when server had no
285-
// information about actual protocols, so we convert it to peer result
286-
// without protocol information
287-
return {
288-
Schema: 'peer',
289-
ID: peerIdFromString(record.ID),
290-
Addrs: record.Addrs?.map(multiaddr) ?? [],
291-
Protocol: record.Protocol
292-
}
280+
if (record.Protocols != null) {
281+
protocols.push(...record.Protocols)
293282
}
294283

295-
if (record.ID != null && Array.isArray(record.Addrs)) {
296-
return {
297-
Schema: 'peer',
298-
ID: peerIdFromString(record.ID),
299-
Addrs: record.Addrs?.map(multiaddr) ?? [],
300-
Protocol: record.Protocol
301-
}
284+
if (record.Protocol != null) {
285+
protocols.push(record.Protocol)
286+
delete record.Protocol
302287
}
303-
}
304288

305-
#handlePeerRecords (peerId: PeerId, record: any): PeerRecord | undefined {
306-
if (record.Schema === 'peer') {
307-
// Peer schema can have additional, user-defined, fields.
308-
record.ID = peerIdFromString(record.ID)
309-
record.Addrs = record.Addrs?.map(multiaddr) ?? []
310-
if (peerId.equals(record.ID)) {
311-
return record
312-
}
289+
return {
290+
...record,
291+
Schema: 'peer',
292+
ID: peerIdFromString(record.ID),
293+
Addrs: multiaddrs,
294+
Protocols: protocols
313295
}
314296
}
315297
}

packages/client/src/index.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,22 @@ import type { Multiaddr } from '@multiformats/multiaddr'
4646
import type { IPNSRecord } from 'ipns'
4747
import type { CID } from 'multiformats/cid'
4848

49+
/**
50+
* A peer that conforms to the [Peer Schema](https://specs.ipfs.tech/routing/http-routing-v1/#peer-schema).
51+
*
52+
* Note that legacy schemas may be reformatted internally by this module.
53+
*
54+
* If `Addrs` is empty, a caller may wish to perform a `findPeer` operation to
55+
* ascertain the peer's multiaddrs.
56+
*
57+
* If `Protocols` is empty, a caller may wish to dial the peer and peform a
58+
* libp2p identify operation to ascertain the peer's supported protocols.
59+
*/
4960
export interface PeerRecord {
5061
Schema: 'peer'
5162
ID: PeerId
52-
Addrs?: Multiaddr[]
53-
Protocol: string
54-
Metadata?: string
63+
Addrs: Multiaddr[]
64+
Protocols: string[]
5565
}
5666

5767
export interface DelegatedRoutingV1HttpApiClientInit {

packages/client/test/index.spec.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* eslint-env mocha */
22

3+
import { peerIdFromString } from '@libp2p/peer-id'
34
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
5+
import { multiaddr } from '@multiformats/multiaddr'
46
import { expect } from 'aegir/chai'
57
import { create as createIpnsRecord, marshal as marshalIpnsRecord } from 'ipns'
68
import all from 'it-all'
@@ -108,7 +110,7 @@ describe('delegated-routing-v1-http-api-client', () => {
108110
expect(provs).to.be.empty()
109111
})
110112

111-
it('should find peers and only accepts correct peer records', async () => {
113+
it('should conform records to peer schema', async () => {
112114
const peerId = await createEd25519PeerId()
113115

114116
const records = [{
@@ -124,7 +126,7 @@ describe('delegated-routing-v1-http-api-client', () => {
124126
ID: peerId.toString(),
125127
Addrs: ['/ip4/41.41.41.41/tcp/1234']
126128
}, {
127-
Protocol: 'transport-bitswap',
129+
Protocols: ['transport-bitswap'],
128130
Schema: 'peer',
129131
Metadata: 'gBI=',
130132
ID: peerId.toString(),
@@ -135,6 +137,40 @@ describe('delegated-routing-v1-http-api-client', () => {
135137
Metadata: 'gBI=',
136138
ID: (await createEd25519PeerId()).toString(),
137139
Addrs: ['/ip4/42.42.42.42/tcp/1234']
140+
}, {
141+
Schema: 'peer',
142+
ID: (await createEd25519PeerId()).toString()
143+
}]
144+
145+
const peers = [{
146+
Protocols: ['transport-bitswap'],
147+
Schema: 'peer',
148+
Metadata: 'gBI=',
149+
ID: peerIdFromString(records[0].ID),
150+
Addrs: [multiaddr('/ip4/41.41.41.41/tcp/1234')]
151+
}, {
152+
Protocols: ['transport-saddle'],
153+
Schema: 'peer',
154+
Metadata: 'gBI=',
155+
ID: peerIdFromString(records[1].ID),
156+
Addrs: [multiaddr('/ip4/41.41.41.41/tcp/1234')]
157+
}, {
158+
Protocols: ['transport-bitswap'],
159+
Schema: 'peer',
160+
Metadata: 'gBI=',
161+
ID: peerIdFromString(records[2].ID),
162+
Addrs: [multiaddr('/ip4/42.42.42.42/tcp/1234')]
163+
}, {
164+
Protocols: ['transport-bitswap'],
165+
Schema: 'peer',
166+
Metadata: 'gBI=',
167+
ID: peerIdFromString(records[3].ID),
168+
Addrs: [multiaddr('/ip4/42.42.42.42/tcp/1234')]
169+
}, {
170+
Protocols: [],
171+
Schema: 'peer',
172+
ID: peerIdFromString(records[4].ID),
173+
Addrs: []
138174
}]
139175

140176
// load peer for the router to fetch
@@ -145,12 +181,14 @@ describe('delegated-routing-v1-http-api-client', () => {
145181

146182
const peerRecords = await all(client.getPeers(peerId))
147183
expect(peerRecords.map(peerRecord => ({
184+
...peerRecord,
185+
ID: peerRecord.ID.toString(),
186+
Addrs: peerRecord.Addrs?.map(ma => ma.toString()) ?? []
187+
}))).to.deep.equal(peers.map(peerRecord => ({
148188
...peerRecord,
149189
ID: peerRecord.ID.toString(),
150190
Addrs: peerRecord.Addrs?.map(ma => ma.toString())
151-
}))).to.deep.equal([
152-
records[2]
153-
])
191+
})))
154192
})
155193

156194
it('should get ipns record', async () => {

0 commit comments

Comments
 (0)