1
1
import { randomBytes } from '@libp2p/crypto'
2
- import { AbortError , InvalidMessageError , ProtocolError , TimeoutError } from '@libp2p/interface'
3
- import first from 'it-first'
4
- import { pipe } from 'it-pipe'
2
+ import { ProtocolError , TimeoutError } from '@libp2p/interface'
3
+ import { byteStream } from 'it-byte-stream'
5
4
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
6
5
import { PROTOCOL_PREFIX , PROTOCOL_NAME , PING_LENGTH , PROTOCOL_VERSION , TIMEOUT , MAX_INBOUND_STREAMS , MAX_OUTBOUND_STREAMS } from './constants.js'
7
6
import type { PingServiceComponents , PingServiceInit , PingService as PingServiceInterface } from './index.js'
@@ -60,37 +59,29 @@ export class PingService implements Startable, PingServiceInterface {
60
59
61
60
const { stream } = data
62
61
const start = Date . now ( )
63
-
64
- const signal = AbortSignal . timeout ( this . timeout )
65
- signal . addEventListener ( 'abort' , ( ) => {
66
- stream ?. abort ( new TimeoutError ( 'ping timeout' ) )
62
+ const bytes = byteStream ( stream )
63
+
64
+ Promise . resolve ( ) . then ( async ( ) => {
65
+ while ( true ) {
66
+ const signal = AbortSignal . timeout ( this . timeout )
67
+ signal . addEventListener ( 'abort' , ( ) => {
68
+ stream ?. abort ( new TimeoutError ( 'ping timeout' ) )
69
+ } )
70
+
71
+ const buf = await bytes . read ( PING_LENGTH , {
72
+ signal
73
+ } )
74
+ await bytes . write ( buf , {
75
+ signal
76
+ } )
77
+ }
67
78
} )
68
-
69
- void pipe (
70
- stream ,
71
- async function * ( source ) {
72
- let received = 0
73
-
74
- for await ( const buf of source ) {
75
- received += buf . byteLength
76
-
77
- if ( received > PING_LENGTH ) {
78
- stream ?. abort ( new InvalidMessageError ( 'Too much data received' ) )
79
- return
80
- }
81
-
82
- yield buf
83
- }
84
- } ,
85
- stream
86
- )
87
79
. catch ( err => {
88
80
this . log . error ( 'incoming ping from %p failed with error' , data . connection . remotePeer , err )
89
81
stream ?. abort ( err )
90
82
} )
91
83
. finally ( ( ) => {
92
84
const ms = Date . now ( ) - start
93
-
94
85
this . log ( 'incoming ping from %p complete in %dms' , data . connection . remotePeer , ms )
95
86
} )
96
87
}
@@ -105,7 +96,6 @@ export class PingService implements Startable, PingServiceInterface {
105
96
const data = randomBytes ( PING_LENGTH )
106
97
const connection = await this . components . connectionManager . openConnection ( peer , options )
107
98
let stream : Stream | undefined
108
- let onAbort = ( ) : void => { }
109
99
110
100
if ( options . signal == null ) {
111
101
const signal = AbortSignal . timeout ( this . timeout )
@@ -122,25 +112,15 @@ export class PingService implements Startable, PingServiceInterface {
122
112
runOnLimitedConnection : this . runOnLimitedConnection
123
113
} )
124
114
125
- onAbort = ( ) => {
126
- stream ?. abort ( new AbortError ( ) )
127
- }
128
-
129
- // make stream abortable
130
- options . signal ?. addEventListener ( 'abort' , onAbort , { once : true } )
115
+ const bytes = byteStream ( stream )
131
116
132
- const result = await pipe (
133
- [ data ] ,
134
- stream ,
135
- async ( source ) => first ( source )
136
- )
117
+ const [ , result ] = await Promise . all ( [
118
+ bytes . write ( data , options ) ,
119
+ bytes . read ( PING_LENGTH , options )
120
+ ] )
137
121
138
122
const ms = Date . now ( ) - start
139
123
140
- if ( result == null ) {
141
- throw new ProtocolError ( `Did not receive a ping ack after ${ ms } ms` )
142
- }
143
-
144
124
if ( ! uint8ArrayEquals ( data , result . subarray ( ) ) ) {
145
125
throw new ProtocolError ( `Received wrong ping ack after ${ ms } ms` )
146
126
}
@@ -155,9 +135,8 @@ export class PingService implements Startable, PingServiceInterface {
155
135
156
136
throw err
157
137
} finally {
158
- options . signal ?. removeEventListener ( 'abort' , onAbort )
159
138
if ( stream != null ) {
160
- await stream . close ( )
139
+ await stream . close ( options )
161
140
}
162
141
}
163
142
}
0 commit comments