@@ -20,13 +20,14 @@ let server: SocketCluster;
2020let socket ;
2121let connect ;
2222let emit ;
23+ let invalidOpcode ;
2324let ping ;
2425let pong ;
2526let send ;
2627
2728const headers = {
2829 version : "2.1.0" ,
29- port : " 4009" ,
30+ port : 4009 ,
3031 height : 1 ,
3132 "Content-Type" : "application/json" ,
3233} ;
@@ -61,6 +62,7 @@ beforeAll(async () => {
6162
6263 ping = ( ) => socket . transport . socket . ping ( ) ;
6364 pong = ( ) => socket . transport . socket . pong ( ) ;
65+ invalidOpcode = ( ) => socket . transport . socket . _socket . write ( Buffer . from ( "8780d0b6fbd2" , "hex" ) ) ;
6466
6567 jest . spyOn ( processor , "validateAndAcceptPeer" ) . mockImplementation ( jest . fn ( ) ) ;
6668} ) ;
@@ -115,14 +117,17 @@ describe("Peer socket endpoint", () => {
115117 expect ( data ) . toEqual ( { } ) ;
116118 } ) ;
117119
118- it ( "should throw validation error when sending wrong data" , async ( ) => {
120+ it ( "should throw error when sending wrong data" , async ( ) => {
119121 await delay ( 1000 ) ;
120122 await expect (
121123 emit ( "p2p.peer.postBlock" , {
122124 data : { } ,
123125 headers,
124126 } ) ,
125- ) . rejects . toHaveProperty ( "name" , "Error" ) ;
127+ ) . rejects . toHaveProperty ( "name" , "BadConnectionError" ) ;
128+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
129+ server . killWorkers ( { immediate : true } ) ;
130+ await delay ( 2000 ) ; // give time to workers to respawn
126131 } ) ;
127132
128133 it ( "should throw error when sending wrong buffer" , async ( ) => {
@@ -134,7 +139,37 @@ describe("Peer socket endpoint", () => {
134139 } ,
135140 headers,
136141 } ) ,
137- ) . rejects . toHaveProperty ( "name" , "BadConnectionError" ) ;
142+ ) . rejects . toHaveProperty ( "name" , "Error" ) ;
143+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
144+ server . killWorkers ( { immediate : true } ) ;
145+ await delay ( 2000 ) ; // give time to workers to respawn
146+ } ) ;
147+
148+ it ( "should throw error if too many transactions are in the block" , async ( ) => {
149+ await delay ( 2000 ) ;
150+ const dummyBlock = BlockFactory . createDummy ( ) ;
151+ const transaction = TransactionFactory . transfer ( wallets [ 0 ] . address , 111 )
152+ . withNetwork ( "unitnet" )
153+ . withPassphrase ( "one two three" )
154+ . build ( ) ;
155+
156+ for ( let i = 0 ; i < 1000 ; i ++ ) {
157+ dummyBlock . transactions . push ( transaction [ 0 ] ) ;
158+ }
159+
160+ dummyBlock . data . numberOfTransactions = 1000 ;
161+
162+ await expect (
163+ emit ( "p2p.peer.postBlock" , {
164+ data : {
165+ block : Blocks . Serializer . serializeWithTransactions ( {
166+ ...dummyBlock . data ,
167+ transactions : dummyBlock . transactions . map ( tx => tx . data ) ,
168+ } ) ,
169+ } ,
170+ headers,
171+ } ) ,
172+ ) . rejects . toHaveProperty ( "name" , "Error" ) ;
138173 } ) ;
139174 } ) ;
140175
@@ -155,29 +190,30 @@ describe("Peer socket endpoint", () => {
155190 // because our mocking makes all transactions to be invalid (already in cache)
156191 } ) ;
157192
158- it ( "should throw validation error when sending too much transactions" , async ( ) => {
193+ it ( "should reject when sending too much transactions" , async ( ) => {
159194 const transactions = TransactionFactory . transfer ( wallets [ 0 ] . address , 111 )
160195 . withNetwork ( "unitnet" )
161196 . withPassphrase ( "one two three" )
162197 . create ( 50 ) ;
163198
164- // TODO: test makes no sense anymore
165199 await expect (
166200 emit ( "p2p.peer.postTransactions" , {
167201 data : { transactions } ,
168202 headers,
169203 } ) ,
170- ) . toResolve ( ) ;
204+ ) . toReject ( ) ;
205+
206+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
207+ server . killWorkers ( { immediate : true } ) ;
208+ await delay ( 2000 ) ; // give time to workers to respawn
171209 } ) ;
172210
173211 it ( "should disconnect the client if it sends an invalid message payload" , async ( ) => {
212+ connect ( ) ;
174213 await delay ( 1000 ) ;
175214
176215 expect ( socket . state ) . toBe ( "open" ) ;
177216
178- send ( '{"event": "#handshake", "data": {}, "cid": 1}' ) ;
179- await delay ( 500 ) ;
180-
181217 send ( "Invalid payload" ) ;
182218 await delay ( 1000 ) ;
183219
@@ -194,9 +230,6 @@ describe("Peer socket endpoint", () => {
194230
195231 expect ( socket . state ) . toBe ( "open" ) ;
196232
197- send ( '{"event": "#handshake", "data": {}, "cid": 1}' ) ;
198- await delay ( 500 ) ;
199-
200233 send ( "#2" ) ;
201234 await delay ( 1000 ) ;
202235
@@ -242,11 +275,58 @@ describe("Peer socket endpoint", () => {
242275 server . killWorkers ( { immediate : true } ) ;
243276 await delay ( 2000 ) ; // give time to workers to respawn
244277 } ) ;
278+
279+ it ( "should block the client if it sends an invalid opcode" , async ( ) => {
280+ connect ( ) ;
281+ await delay ( 1000 ) ;
282+
283+ expect ( socket . state ) . toBe ( "open" ) ;
284+
285+ invalidOpcode ( ) ;
286+ await delay ( 500 ) ;
287+ expect ( socket . state ) . toBe ( "closed" ) ;
288+ await delay ( 500 ) ;
289+ connect ( ) ;
290+ await delay ( 500 ) ;
291+ expect ( socket . state ) . toBe ( "closed" ) ;
292+
293+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
294+ server . killWorkers ( { immediate : true } ) ;
295+ await delay ( 2000 ) ; // give time to workers to respawn
296+ } ) ;
245297 } ) ;
246298 } ) ;
247299
248300 describe ( "Socket errors" , ( ) => {
301+ it ( "should disconnect all sockets from same ip if another connection is made from the same IP address" , async ( ) => {
302+ connect ( ) ;
303+ await delay ( 1000 ) ;
304+
305+ expect ( socket . state ) . toBe ( "open" ) ;
306+
307+ const secondSocket = socketCluster . create ( {
308+ port : 4007 ,
309+ hostname : "127.0.0.1" ,
310+ multiplex : false ,
311+ } ) ;
312+ secondSocket . on ( "error" , ( ) => {
313+ //
314+ } ) ;
315+
316+ secondSocket . connect ( ) ;
317+
318+ await delay ( 1000 ) ;
319+
320+ expect ( socket . state ) . toBe ( "closed" ) ;
321+ expect ( secondSocket . state ) . toBe ( "open" ) ;
322+
323+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
324+ server . killWorkers ( { immediate : true } ) ;
325+ await delay ( 2000 ) ; // give time to workers to respawn
326+ } ) ;
327+
249328 it ( "should accept the request when below rate limit" , async ( ) => {
329+ connect ( ) ;
250330 await delay ( 1000 ) ;
251331 for ( let i = 0 ; i < 2 ; i ++ ) {
252332 const { data } = await emit ( "p2p.peer.getStatus" , {
@@ -288,15 +368,16 @@ describe("Peer socket endpoint", () => {
288368
289369 const block = BlockFactory . createDummy ( ) ;
290370
291- const postBlock = ( ) => emit ( "p2p.peer.postBlock" , {
292- headers,
293- data : {
294- block : Blocks . Serializer . serializeWithTransactions ( {
295- ...block . data ,
296- transactions : block . transactions . map ( tx => tx . data ) ,
297- } ) ,
298- } ,
299- } ) ;
371+ const postBlock = ( ) =>
372+ emit ( "p2p.peer.postBlock" , {
373+ headers,
374+ data : {
375+ block : Blocks . Serializer . serializeWithTransactions ( {
376+ ...block . data ,
377+ transactions : block . transactions . map ( tx => tx . data ) ,
378+ } ) ,
379+ } ,
380+ } ) ;
300381
301382 await expect ( postBlock ( ) ) . toResolve ( ) ;
302383 await expect ( postBlock ( ) ) . toResolve ( ) ;
@@ -326,9 +407,14 @@ describe("Peer socket endpoint", () => {
326407 } ,
327408 ) ,
328409 ) . rejects . toHaveProperty ( "name" , "BadConnectionError" ) ;
410+
411+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
412+ server . killWorkers ( { immediate : true } ) ;
413+ await delay ( 2000 ) ; // give time to workers to respawn
329414 } ) ;
330415
331416 it ( "should close the connection when the event does not start with p2p" , async ( ) => {
417+ connect ( ) ;
332418 await delay ( 1000 ) ;
333419
334420 await expect (
@@ -337,9 +423,14 @@ describe("Peer socket endpoint", () => {
337423 data : { } ,
338424 } ) ,
339425 ) . rejects . toHaveProperty ( "name" , "BadConnectionError" ) ;
426+
427+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
428+ server . killWorkers ( { immediate : true } ) ;
429+ await delay ( 2000 ) ; // give time to workers to respawn
340430 } ) ;
341431
342432 it ( "should close the connection when the version is invalid" , async ( ) => {
433+ connect ( ) ;
343434 await delay ( 1000 ) ;
344435
345436 await expect (
@@ -348,9 +439,13 @@ describe("Peer socket endpoint", () => {
348439 data : { } ,
349440 } ) ,
350441 ) . rejects . toHaveProperty ( "name" , "BadConnectionError" ) ;
442+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
443+ server . killWorkers ( { immediate : true } ) ;
444+ await delay ( 2000 ) ; // give time to workers to respawn
351445 } ) ;
352446
353447 it ( "should close the connection and prevent reconnection if blocked" , async ( ) => {
448+ connect ( ) ;
354449 await delay ( 1000 ) ;
355450
356451 await emit ( "p2p.peer.getPeers" , {
@@ -375,6 +470,25 @@ describe("Peer socket endpoint", () => {
375470 await delay ( 1000 ) ;
376471
377472 expect ( socket . state ) . not . toBe ( "open" ) ;
473+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
474+ server . killWorkers ( { immediate : true } ) ;
475+ await delay ( 2000 ) ; // give time to workers to respawn
476+ } ) ;
477+
478+ it ( "should close the connection when using unsupported event messages" , async ( ) => {
479+ connect ( ) ;
480+ await delay ( 1000 ) ;
481+
482+ await expect (
483+ emit ( "#subscribe" , {
484+ headers,
485+ data : { } ,
486+ } ) ,
487+ ) . rejects . toHaveProperty ( "name" , "BadConnectionError" ) ;
488+
489+ // kill workers to reset ipLastError (or we won't pass handshake for 1 minute)
490+ server . killWorkers ( { immediate : true } ) ;
491+ await delay ( 2000 ) ; // give time to workers to respawn
378492 } ) ;
379493
380494 it ( "should close the connection if it sends data after a disconnect packet" , async ( ) => {
@@ -394,5 +508,31 @@ describe("Peer socket endpoint", () => {
394508 server . killWorkers ( { immediate : true } ) ;
395509 await delay ( 2000 ) ; // give time to workers to respawn
396510 } ) ;
511+
512+ it ( "should close the connection when the JSON includes additional properties" , async ( ) => {
513+ connect ( ) ;
514+ await delay ( 1000 ) ;
515+ const payload : any = { } ;
516+ payload . event = "p2p.peer.getCommonBlocks" ;
517+ payload . data = { data : { ids : [ "1" ] } , headers : { } } ;
518+ payload . cid = 1 ;
519+
520+ const symbol = String . fromCharCode ( 42 ) ;
521+ for ( let i = 0 ; i < 30000 ; i ++ ) {
522+ const char = String . fromCharCode ( i ) ;
523+ if ( JSON . stringify ( String . fromCharCode ( i ) ) . length === 3 ) {
524+ payload . data [ char ] = 1 ;
525+ payload . data [ symbol + char ] = 1 ;
526+ payload . data [ symbol + char + symbol ] = 1 ;
527+ payload . data [ char ] = 1 ;
528+ }
529+ }
530+
531+ const stringifiedPayload = JSON . stringify ( payload ) . replace ( / / g, "" ) ;
532+ expect ( socket . state ) . toBe ( "open" ) ;
533+ send ( stringifiedPayload ) ;
534+ await delay ( 500 ) ;
535+ expect ( socket . state ) . not . toBe ( "open" ) ;
536+ } ) ;
397537 } ) ;
398538} ) ;
0 commit comments