@libp2p/identify 2.1.5 → 3.0.0-18dd3cb26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/identify.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable complexity */
2
2
 
3
- import { CodeError, serviceCapabilities, setMaxListeners } from '@libp2p/interface'
4
- import { peerIdFromKeys } from '@libp2p/peer-id'
3
+ import { publicKeyFromProtobuf, publicKeyToProtobuf } from '@libp2p/crypto/keys'
4
+ import { InvalidMessageError, serviceCapabilities, setMaxListeners } from '@libp2p/interface'
5
+ import { peerIdFromCID } from '@libp2p/peer-id'
5
6
  import { RecordEnvelope, PeerRecord } from '@libp2p/peer-record'
6
7
  import { protocols } from '@multiformats/multiaddr'
7
8
  import { IP_OR_DOMAIN } from '@multiformats/multiaddr-matcher'
@@ -53,7 +54,7 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
53
54
  try {
54
55
  stream = await connection.newStream(this.protocol, {
55
56
  ...options,
56
- runOnTransientConnection: this.runOnTransientConnection
57
+ runOnLimitedConnection: this.runOnLimitedConnection
57
58
  })
58
59
 
59
60
  const pb = pbStream(stream, {
@@ -81,17 +82,18 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
81
82
  } = message
82
83
 
83
84
  if (publicKey == null) {
84
- throw new CodeError('public key was missing from identify message', 'ERR_MISSING_PUBLIC_KEY')
85
+ throw new InvalidMessageError('public key was missing from identify message')
85
86
  }
86
87
 
87
- const id = await peerIdFromKeys(publicKey)
88
+ const key = publicKeyFromProtobuf(publicKey)
89
+ const id = peerIdFromCID(key.toCID())
88
90
 
89
91
  if (!connection.remotePeer.equals(id)) {
90
- throw new CodeError('identified peer does not match the expected peer', 'ERR_INVALID_PEER')
92
+ throw new InvalidMessageError('identified peer does not match the expected peer')
91
93
  }
92
94
 
93
95
  if (this.peerId.equals(id)) {
94
- throw new CodeError('identified peer is our own peer id?', 'ERR_INVALID_PEER')
96
+ throw new InvalidMessageError('identified peer is our own peer id?')
95
97
  }
96
98
 
97
99
  // Get the observedAddr if there is one
@@ -121,7 +123,6 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
121
123
  setMaxListeners(Infinity, signal)
122
124
 
123
125
  try {
124
- const publicKey = this.peerId.publicKey ?? new Uint8Array(0)
125
126
  const peerData = await this.peerStore.get(this.peerId)
126
127
  const multiaddrs = this.addressManager.getAddresses().map(ma => ma.decapsulateCode(protocols('p2p').code))
127
128
  let signedPeerRecord = peerData.peerRecordEnvelope
@@ -132,7 +133,7 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
132
133
  multiaddrs
133
134
  })
134
135
 
135
- const envelope = await RecordEnvelope.seal(peerRecord, this.peerId)
136
+ const envelope = await RecordEnvelope.seal(peerRecord, this.privateKey)
136
137
  signedPeerRecord = envelope.marshal().subarray()
137
138
  }
138
139
 
@@ -147,7 +148,7 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
147
148
  await pb.write({
148
149
  protocolVersion: this.host.protocolVersion,
149
150
  agentVersion: this.host.agentVersion,
150
- publicKey,
151
+ publicKey: publicKeyToProtobuf(this.privateKey.publicKey),
151
152
  listenAddrs: multiaddrs.map(addr => addr.bytes),
152
153
  signedPeerRecord,
153
154
  observedAddr,
package/src/index.ts CHANGED
@@ -43,7 +43,7 @@
43
43
 
44
44
  import { IdentifyPush as IdentifyPushClass } from './identify-push.js'
45
45
  import { Identify as IdentifyClass } from './identify.js'
46
- import type { AbortOptions, IdentifyResult, Libp2pEvents, ComponentLogger, NodeInfo, TypedEventTarget, PeerId, PeerStore, Connection } from '@libp2p/interface'
46
+ import type { AbortOptions, IdentifyResult, Libp2pEvents, ComponentLogger, NodeInfo, TypedEventTarget, PeerId, PeerStore, Connection, PrivateKey } from '@libp2p/interface'
47
47
  import type { AddressManager, ConnectionManager, Registrar } from '@libp2p/interface-internal'
48
48
 
49
49
  export interface IdentifyInit {
@@ -99,7 +99,7 @@ export interface IdentifyInit {
99
99
  *
100
100
  * @default true
101
101
  */
102
- runOnTransientConnection?: boolean
102
+ runOnLimitedConnection?: boolean
103
103
 
104
104
  /**
105
105
  * Whether to automatically run identify on newly opened connections
@@ -127,6 +127,7 @@ export interface IdentifyPushInit extends Omit<IdentifyInit, 'runOnConnectionOpe
127
127
 
128
128
  export interface IdentifyComponents {
129
129
  peerId: PeerId
130
+ privateKey: PrivateKey
130
131
  peerStore: PeerStore
131
132
  registrar: Registrar
132
133
  addressManager: AddressManager
package/src/pb/message.ts CHANGED
@@ -4,8 +4,7 @@
4
4
  /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
5
5
  /* eslint-disable @typescript-eslint/no-empty-interface */
6
6
 
7
- import { encodeMessage, decodeMessage, message } from 'protons-runtime'
8
- import type { Codec } from 'protons-runtime'
7
+ import { type Codec, decodeMessage, type DecodeOptions, encodeMessage, MaxLengthError, message } from 'protons-runtime'
9
8
  import type { Uint8ArrayList } from 'uint8arraylist'
10
9
 
11
10
  export interface Identify {
@@ -70,7 +69,7 @@ export namespace Identify {
70
69
  if (opts.lengthDelimited !== false) {
71
70
  w.ldelim()
72
71
  }
73
- }, (reader, length) => {
72
+ }, (reader, length, opts = {}) => {
74
73
  const obj: any = {
75
74
  listenAddrs: [],
76
75
  protocols: []
@@ -82,30 +81,46 @@ export namespace Identify {
82
81
  const tag = reader.uint32()
83
82
 
84
83
  switch (tag >>> 3) {
85
- case 5:
84
+ case 5: {
86
85
  obj.protocolVersion = reader.string()
87
86
  break
88
- case 6:
87
+ }
88
+ case 6: {
89
89
  obj.agentVersion = reader.string()
90
90
  break
91
- case 1:
91
+ }
92
+ case 1: {
92
93
  obj.publicKey = reader.bytes()
93
94
  break
94
- case 2:
95
+ }
96
+ case 2: {
97
+ if (opts.limits?.listenAddrs != null && obj.listenAddrs.length === opts.limits.listenAddrs) {
98
+ throw new MaxLengthError('Decode error - map field "listenAddrs" had too many elements')
99
+ }
100
+
95
101
  obj.listenAddrs.push(reader.bytes())
96
102
  break
97
- case 4:
103
+ }
104
+ case 4: {
98
105
  obj.observedAddr = reader.bytes()
99
106
  break
100
- case 3:
107
+ }
108
+ case 3: {
109
+ if (opts.limits?.protocols != null && obj.protocols.length === opts.limits.protocols) {
110
+ throw new MaxLengthError('Decode error - map field "protocols" had too many elements')
111
+ }
112
+
101
113
  obj.protocols.push(reader.string())
102
114
  break
103
- case 8:
115
+ }
116
+ case 8: {
104
117
  obj.signedPeerRecord = reader.bytes()
105
118
  break
106
- default:
119
+ }
120
+ default: {
107
121
  reader.skipType(tag & 7)
108
122
  break
123
+ }
109
124
  }
110
125
  }
111
126
 
@@ -120,7 +135,7 @@ export namespace Identify {
120
135
  return encodeMessage(obj, Identify.codec())
121
136
  }
122
137
 
123
- export const decode = (buf: Uint8Array | Uint8ArrayList): Identify => {
124
- return decodeMessage(buf, Identify.codec())
138
+ export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<Identify>): Identify => {
139
+ return decodeMessage(buf, Identify.codec(), opts)
125
140
  }
126
141
  }
package/src/utils.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { CodeError } from '@libp2p/interface'
2
- import { peerIdFromKeys } from '@libp2p/peer-id'
1
+ import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'
2
+ import { InvalidMessageError } from '@libp2p/interface'
3
+ import { peerIdFromCID, peerIdFromPublicKey } from '@libp2p/peer-id'
3
4
  import { RecordEnvelope, PeerRecord } from '@libp2p/peer-record'
4
5
  import { type Multiaddr, multiaddr } from '@multiformats/multiaddr'
5
6
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
@@ -7,7 +8,7 @@ import { isNode, isBrowser, isWebWorker, isElectronMain, isElectronRenderer, isR
7
8
  import { IDENTIFY_PROTOCOL_VERSION, MAX_IDENTIFY_MESSAGE_SIZE, MAX_PUSH_CONCURRENCY } from './consts.js'
8
9
  import type { IdentifyComponents, IdentifyInit } from './index.js'
9
10
  import type { Identify as IdentifyMessage } from './pb/message.js'
10
- import type { Libp2pEvents, IdentifyResult, SignedPeerRecord, Logger, Connection, TypedEventTarget, Peer, PeerData, PeerStore, NodeInfo, Startable, PeerId, IncomingStreamData } from '@libp2p/interface'
11
+ import type { Libp2pEvents, IdentifyResult, SignedPeerRecord, Logger, Connection, TypedEventTarget, Peer, PeerData, PeerStore, NodeInfo, Startable, PeerId, IncomingStreamData, PrivateKey } from '@libp2p/interface'
11
12
  import type { AddressManager, Registrar } from '@libp2p/interface-internal'
12
13
 
13
14
  export const defaultValues = {
@@ -19,7 +20,7 @@ export const defaultValues = {
19
20
  maxMessageSize: MAX_IDENTIFY_MESSAGE_SIZE,
20
21
  runOnConnectionOpen: true,
21
22
  runOnSelfUpdate: true,
22
- runOnTransientConnection: true,
23
+ runOnLimitedConnection: true,
23
24
  concurrency: MAX_PUSH_CONCURRENCY
24
25
  }
25
26
 
@@ -56,7 +57,7 @@ export async function consumeIdentifyMessage (peerStore: PeerStore, events: Type
56
57
  log('received identify from %p', connection.remotePeer)
57
58
 
58
59
  if (message == null) {
59
- throw new CodeError('message was null or undefined', 'ERR_INVALID_MESSAGE')
60
+ throw new InvalidMessageError('message was null or undefined')
60
61
  }
61
62
 
62
63
  const peer: PeerData = {}
@@ -73,13 +74,14 @@ export async function consumeIdentifyMessage (peerStore: PeerStore, events: Type
73
74
  }
74
75
 
75
76
  if (message.publicKey != null) {
76
- peer.publicKey = message.publicKey
77
-
78
- const peerId = await peerIdFromKeys(message.publicKey)
77
+ const publicKey = publicKeyFromProtobuf(message.publicKey)
78
+ const peerId = peerIdFromPublicKey(publicKey)
79
79
 
80
80
  if (!peerId.equals(connection.remotePeer)) {
81
- throw new CodeError('public key did not match remote PeerId', 'ERR_INVALID_PUBLIC_KEY')
81
+ throw new InvalidMessageError('public key did not match remote PeerId')
82
82
  }
83
+
84
+ peer.publicKey = publicKey
83
85
  }
84
86
 
85
87
  let output: SignedPeerRecord | undefined
@@ -91,15 +93,16 @@ export async function consumeIdentifyMessage (peerStore: PeerStore, events: Type
91
93
  let peerRecordEnvelope = message.signedPeerRecord
92
94
  const envelope = await RecordEnvelope.openAndCertify(peerRecordEnvelope, PeerRecord.DOMAIN)
93
95
  let peerRecord = PeerRecord.createFromProtobuf(envelope.payload)
96
+ const envelopePeer = peerIdFromCID(envelope.publicKey.toCID())
94
97
 
95
98
  // Verify peerId
96
- if (!peerRecord.peerId.equals(envelope.peerId)) {
97
- throw new CodeError('signing key does not match PeerId in the PeerRecord', 'ERR_INVALID_SIGNING_KEY')
99
+ if (!peerRecord.peerId.equals(envelopePeer)) {
100
+ throw new InvalidMessageError('signing key does not match PeerId in the PeerRecord')
98
101
  }
99
102
 
100
103
  // Make sure remote peer is the one sending the record
101
104
  if (!connection.remotePeer.equals(peerRecord.peerId)) {
102
- throw new CodeError('signing key does not match remote PeerId', 'ERR_INVALID_PEER_RECORD_KEY')
105
+ throw new InvalidMessageError('signing key does not match remote PeerId')
103
106
  }
104
107
 
105
108
  let existingPeer: Peer | undefined
@@ -107,7 +110,7 @@ export async function consumeIdentifyMessage (peerStore: PeerStore, events: Type
107
110
  try {
108
111
  existingPeer = await peerStore.get(peerRecord.peerId)
109
112
  } catch (err: any) {
110
- if (err.code !== 'ERR_NOT_FOUND') {
113
+ if (err.name !== 'NotFoundError') {
111
114
  throw err
112
115
  }
113
116
  }
@@ -199,6 +202,7 @@ export abstract class AbstractIdentify implements Startable {
199
202
  protected started: boolean
200
203
  protected readonly timeout: number
201
204
  protected readonly peerId: PeerId
205
+ protected readonly privateKey: PrivateKey
202
206
  protected readonly peerStore: PeerStore
203
207
  protected readonly registrar: Registrar
204
208
  protected readonly addressManager: AddressManager
@@ -207,13 +211,14 @@ export abstract class AbstractIdentify implements Startable {
207
211
  protected readonly maxMessageSize: number
208
212
  protected readonly maxObservedAddresses: number
209
213
  protected readonly events: TypedEventTarget<Libp2pEvents>
210
- protected readonly runOnTransientConnection: boolean
214
+ protected readonly runOnLimitedConnection: boolean
211
215
  protected readonly log: Logger
212
216
 
213
217
  constructor (components: IdentifyComponents, init: AbstractIdentifyInit) {
214
218
  this.protocol = init.protocol
215
219
  this.started = false
216
220
  this.peerId = components.peerId
221
+ this.privateKey = components.privateKey
217
222
  this.peerStore = components.peerStore
218
223
  this.registrar = components.registrar
219
224
  this.addressManager = components.addressManager
@@ -225,7 +230,7 @@ export abstract class AbstractIdentify implements Startable {
225
230
  this.maxOutboundStreams = init.maxOutboundStreams ?? defaultValues.maxOutboundStreams
226
231
  this.maxMessageSize = init.maxMessageSize ?? defaultValues.maxMessageSize
227
232
  this.maxObservedAddresses = init.maxObservedAddresses ?? defaultValues.maxObservedAddresses
228
- this.runOnTransientConnection = init.runOnTransientConnection ?? defaultValues.runOnTransientConnection
233
+ this.runOnLimitedConnection = init.runOnLimitedConnection ?? defaultValues.runOnLimitedConnection
229
234
 
230
235
  // Store self host metadata
231
236
  this.host = {
@@ -257,7 +262,7 @@ export abstract class AbstractIdentify implements Startable {
257
262
  }, {
258
263
  maxInboundStreams: this.maxInboundStreams,
259
264
  maxOutboundStreams: this.maxOutboundStreams,
260
- runOnTransientConnection: this.runOnTransientConnection
265
+ runOnLimitedConnection: this.runOnLimitedConnection
261
266
  })
262
267
 
263
268
  this.started = true
@@ -1,18 +0,0 @@
1
- {
2
- "Identify": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.Identify.html",
3
- ".:Identify": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.Identify.html",
4
- "IdentifyComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyComponents.html",
5
- ".:IdentifyComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyComponents.html",
6
- "IdentifyInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyInit.html",
7
- ".:IdentifyInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyInit.html",
8
- "IdentifyPush": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyPush.html",
9
- ".:IdentifyPush": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyPush.html",
10
- "IdentifyPushComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyPushComponents.html",
11
- ".:IdentifyPushComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyPushComponents.html",
12
- "IdentifyPushInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyPushInit.html",
13
- ".:IdentifyPushInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_identify.IdentifyPushInit.html",
14
- "identify": "https://libp2p.github.io/js-libp2p/functions/_libp2p_identify.identify-1.html",
15
- ".:identify": "https://libp2p.github.io/js-libp2p/functions/_libp2p_identify.identify-1.html",
16
- "identifyPush": "https://libp2p.github.io/js-libp2p/functions/_libp2p_identify.identifyPush-1.html",
17
- ".:identifyPush": "https://libp2p.github.io/js-libp2p/functions/_libp2p_identify.identifyPush-1.html"
18
- }