@libp2p/daemon-server 6.0.2 → 7.0.0

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/index.ts CHANGED
@@ -2,27 +2,27 @@
2
2
 
3
3
  import {
4
4
  Request,
5
+ Response,
5
6
  DHTRequest,
6
7
  PeerstoreRequest,
7
8
  PSRequest,
8
9
  StreamInfo
9
10
  } from '@libp2p/daemon-protocol'
10
- import { StreamHandler } from '@libp2p/daemon-protocol/stream-handler'
11
11
  import { passThroughUpgrader } from '@libp2p/daemon-protocol/upgrader'
12
- import { logger } from '@libp2p/logger'
12
+ import { defaultLogger, logger } from '@libp2p/logger'
13
13
  import { peerIdFromBytes } from '@libp2p/peer-id'
14
14
  import { tcp } from '@libp2p/tcp'
15
15
  import { multiaddr, protocols } from '@multiformats/multiaddr'
16
16
  import * as lp from 'it-length-prefixed'
17
+ import { lpStream } from 'it-length-prefixed-stream'
17
18
  import { pipe } from 'it-pipe'
19
+ import { pbStream } from 'it-protobuf-stream'
18
20
  import { CID } from 'multiformats/cid'
19
21
  import { DHTOperations } from './dht.js'
20
22
  import { PubSubOperations } from './pubsub.js'
21
23
  import { ErrorResponse, OkResponse } from './responses.js'
22
24
  import type { GossipSub } from '@chainsafe/libp2p-gossipsub'
23
- import type { Libp2p } from '@libp2p/interface'
24
- import type { Connection, MultiaddrConnection, Stream } from '@libp2p/interface/connection'
25
- import type { Listener, Transport } from '@libp2p/interface/transport'
25
+ import type { Libp2p, Connection, MultiaddrConnection, Stream, Listener, Transport } from '@libp2p/interface'
26
26
  import type { KadDHT } from '@libp2p/kad-dht'
27
27
  import type { Multiaddr } from '@multiformats/multiaddr'
28
28
 
@@ -58,8 +58,11 @@ export class Server implements Libp2pServer {
58
58
 
59
59
  this.multiaddr = multiaddr
60
60
  this.libp2p = libp2pNode
61
- this.tcp = tcp()()
61
+ this.tcp = tcp()({
62
+ logger: defaultLogger()
63
+ })
62
64
  this.listener = this.tcp.createListener({
65
+ // @ts-expect-error connection may actually be a maconn?
63
66
  handler: this.handleConnection.bind(this),
64
67
  upgrader: passThroughUpgrader
65
68
  })
@@ -380,153 +383,160 @@ export class Server implements Libp2pServer {
380
383
  /**
381
384
  * Handles requests for the given connection
382
385
  */
383
- handleConnection (connection: Connection): void {
384
- const daemon = this // eslint-disable-line @typescript-eslint/no-this-alias
385
- // @ts-expect-error connection may actually be a maconn?
386
- const streamHandler = new StreamHandler({ stream: connection, maxLength: LIMIT })
387
-
388
- void pipe(
389
- streamHandler.decoder,
390
- source => (async function * () {
391
- let request: Request
392
-
393
- for await (const buf of source) {
394
- try {
395
- request = Request.decode(buf)
396
-
397
- switch (request.type) {
398
- // Connect to another peer
399
- case Request.Type.CONNECT: {
400
- try {
401
- await daemon.connect(request)
402
- } catch (err: any) {
403
- yield ErrorResponse(err)
404
- break
405
- }
406
- yield OkResponse()
407
- break
386
+ handleConnection (maConn: MultiaddrConnection): void {
387
+ void Promise.resolve().then(async () => {
388
+ const daemon = this // eslint-disable-line @typescript-eslint/no-this-alias
389
+
390
+ const pb = pbStream(maConn, {
391
+ maxDataLength: LIMIT
392
+ })
393
+
394
+ const request = await pb.read(Request)
395
+ log('read', request)
396
+
397
+ try {
398
+ switch (request.type) {
399
+ // Connect to another peer
400
+ case Request.Type.CONNECT: {
401
+ await daemon.connect(request)
402
+ await pb.write({
403
+ type: Response.Type.OK
404
+ }, Response)
405
+
406
+ break
407
+ }
408
+ // Get the daemon peer id and addresses
409
+ case Request.Type.IDENTIFY: {
410
+ await pb.write({
411
+ type: Response.Type.OK,
412
+ identify: {
413
+ id: daemon.libp2p.peerId.toBytes(),
414
+ addrs: daemon.libp2p.getMultiaddrs().map(ma => ma.decapsulateCode(protocols('p2p').code)).map(m => m.bytes)
408
415
  }
409
- // Get the daemon peer id and addresses
410
- case Request.Type.IDENTIFY: {
411
- yield OkResponse({
412
- identify: {
413
- id: daemon.libp2p.peerId.toBytes(),
414
- addrs: daemon.libp2p.getMultiaddrs().map(ma => ma.decapsulateCode(protocols('p2p').code)).map(m => m.bytes)
415
- }
416
- })
417
- break
416
+ }, Response)
417
+
418
+ break
419
+ }
420
+ // Get a list of our current peers
421
+ case Request.Type.LIST_PEERS: {
422
+ const peers = []
423
+ const seen = new Set<string>()
424
+
425
+ for (const connection of daemon.libp2p.getConnections()) {
426
+ const peerId = connection.remotePeer.toString()
427
+
428
+ if (seen.has(peerId)) {
429
+ continue
418
430
  }
419
- // Get a list of our current peers
420
- case Request.Type.LIST_PEERS: {
421
- const peers = []
422
- const seen = new Set<string>()
423
431
 
424
- for (const connection of daemon.libp2p.getConnections()) {
425
- const peerId = connection.remotePeer.toString()
432
+ seen.add(peerId)
433
+
434
+ peers.push({
435
+ id: connection.remotePeer.toBytes(),
436
+ addrs: [connection.remoteAddr.bytes]
437
+ })
438
+ }
426
439
 
427
- if (seen.has(peerId)) {
428
- continue
429
- }
440
+ await pb.write({
441
+ type: Response.Type.OK,
442
+ peers
443
+ }, Response)
430
444
 
431
- seen.add(peerId)
445
+ break
446
+ }
447
+ case Request.Type.STREAM_OPEN: {
448
+ const response = await daemon.openStream(request)
449
+
450
+ // write the response
451
+ await pb.write({
452
+ type: Response.Type.OK,
453
+ streamInfo: response.streamInfo
454
+ }, Response)
455
+
456
+ const stream = pb.unwrap()
457
+
458
+ // then pipe the connection to the client
459
+ await pipe(
460
+ stream,
461
+ response.connection,
462
+ stream
463
+ )
464
+
465
+ // Exit the iterator, no more requests can come through
466
+ break
467
+ }
468
+ case Request.Type.STREAM_HANDLER: {
469
+ await daemon.registerStreamHandler(request)
432
470
 
433
- peers.push({
434
- id: connection.remotePeer.toBytes(),
435
- addrs: [connection.remoteAddr.bytes]
436
- })
437
- }
471
+ // write the response
472
+ await pb.write({
473
+ type: Response.Type.OK
474
+ }, Response)
438
475
 
439
- yield OkResponse({ peers })
440
- break
441
- }
442
- case Request.Type.STREAM_OPEN: {
443
- let response
444
- try {
445
- response = await daemon.openStream(request)
446
- } catch (err: any) {
447
- yield ErrorResponse(err)
448
- break
449
- }
450
-
451
- // write the response
452
- yield OkResponse({
453
- streamInfo: response.streamInfo
454
- })
455
-
456
- const stream = streamHandler.rest()
457
- // then pipe the connection to the client
458
- await pipe(
459
- stream,
460
- response.connection,
461
- async function * (source) {
462
- for await (const list of source) {
463
- yield * list
464
- }
465
- },
466
- stream
467
- )
468
- // Exit the iterator, no more requests can come through
469
- return
470
- }
471
- case Request.Type.STREAM_HANDLER: {
472
- try {
473
- await daemon.registerStreamHandler(request)
474
- } catch (err: any) {
475
- yield ErrorResponse(err)
476
- break
477
- }
478
-
479
- // write the response
480
- yield OkResponse()
481
- break
482
- }
483
- case Request.Type.PEERSTORE: {
484
- if (request.peerStore == null) {
485
- yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
486
- break
487
- }
488
-
489
- yield * daemon.handlePeerStoreRequest(request.peerStore)
490
- break
491
- }
492
- case Request.Type.PUBSUB: {
493
- if (request.pubsub == null) {
494
- yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
495
- break
496
- }
497
-
498
- yield * daemon.handlePubsubRequest(request.pubsub)
499
- break
500
- }
501
- case Request.Type.DHT: {
502
- if (request.dht == null) {
503
- yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
504
- break
505
- }
506
-
507
- yield * daemon.handleDHTRequest(request.dht)
508
- break
509
- }
510
- // Not yet supported or doesn't exist
511
- default:
512
- yield ErrorResponse(new Error('ERR_INVALID_REQUEST_TYPE'))
513
- break
476
+ break
477
+ }
478
+ case Request.Type.PEERSTORE: {
479
+ if (request.peerStore == null) {
480
+ throw new Error('ERR_INVALID_REQUEST')
514
481
  }
515
- } catch (err: any) {
516
- log.error(err)
517
- yield ErrorResponse(err)
518
- continue
482
+
483
+ const stream = pb.unwrap()
484
+ const lp = lpStream(stream)
485
+
486
+ for await (const buf of daemon.handlePeerStoreRequest(request.peerStore)) {
487
+ await lp.write(buf)
488
+ }
489
+
490
+ break
519
491
  }
492
+ case Request.Type.PUBSUB: {
493
+ if (request.pubsub == null) {
494
+ throw new Error('ERR_INVALID_REQUEST')
495
+ }
496
+
497
+ const stream = pb.unwrap()
498
+ const lp = lpStream(stream)
499
+
500
+ for await (const buf of daemon.handlePubsubRequest(request.pubsub)) {
501
+ await lp.write(buf)
502
+ }
503
+
504
+ break
505
+ }
506
+ case Request.Type.DHT: {
507
+ if (request.dht == null) {
508
+ throw new Error('ERR_INVALID_REQUEST')
509
+ }
510
+
511
+ const stream = pb.unwrap()
512
+ const lp = lpStream(stream)
513
+
514
+ for await (const buf of daemon.handleDHTRequest(request.dht)) {
515
+ await lp.write(buf)
516
+ }
517
+
518
+ break
519
+ }
520
+ // Not yet supported or doesn't exist
521
+ default:
522
+ throw new Error('ERR_INVALID_REQUEST_TYPE')
520
523
  }
521
- })(),
522
- async function (source) {
523
- for await (const result of source) {
524
- streamHandler.write(result)
525
- }
524
+ } catch (err: any) {
525
+ log.error(err)
526
+ await pb.write({
527
+ type: Response.Type.ERROR,
528
+ error: {
529
+ msg: err.message
530
+ },
531
+ peers: []
532
+ }, Response)
533
+ } finally {
534
+ await pb.unwrap().close()
526
535
  }
527
- ).catch(err => {
528
- log(err)
529
536
  })
537
+ .catch(err => {
538
+ log.error('error handling incoming connection', err)
539
+ })
530
540
  }
531
541
  }
532
542