diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index efd69b63beab3c42afa4931d281455b617410093..0ce2fa0983f4b3ca873906ba718f1ebee3d11c61 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -13,10 +13,10 @@ import {OtherConstants} from "../../../lib/other_constants" import {Key, verify} from "../../../lib/common-libs/crypto/keyring" import {WS2PServerMessageHandler} from "./interface/WS2PServerMessageHandler" import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" -import { CommonConstants } from '../../../lib/common-libs/constants'; -import { Package } from "../../../lib/common/package"; -import { Constants } from "../../prover/lib/constants"; -import { ProxiesConf } from '../../../lib/proxy'; +import {CommonConstants} from '../../../lib/common-libs/constants'; +import {Package} from "../../../lib/common/package"; +import {Constants} from "../../prover/lib/constants"; +import {ProxiesConf} from '../../../lib/proxy'; const es = require('event-stream') const nuuid = require('node-uuid') @@ -254,12 +254,6 @@ export class WS2PCluster { this.maxLevel1Size = Math.max(newValue, 0) || 0 } - set maxLevel2Peers(newValue:number) { - if (this.ws2pServer) { - this.ws2pServer.maxLevel2Peers = Math.max(newValue, 0) - } - } - get maxLevel2Peers() { if (this.ws2pServer) { return this.ws2pServer.maxLevel2Peers || 0 @@ -484,6 +478,12 @@ export class WS2PCluster { return { sig, message, pub } } + async trimServerConnections() { + if (this.ws2pServer) { + await this.ws2pServer.trimConnections() + } + } + async trimClientConnections() { let serverPubkeys:string[] = [] if (this.ws2pServer) { diff --git a/app/modules/ws2p/lib/WS2PServer.ts b/app/modules/ws2p/lib/WS2PServer.ts index ae79815fe93af6f0c24ebb355e7d404681165748..251f01a631592b2152a1a9599ba11567927f6f38 100644 --- a/app/modules/ws2p/lib/WS2PServer.ts +++ b/app/modules/ws2p/lib/WS2PServer.ts @@ -14,7 +14,6 @@ export class WS2PServer extends events.EventEmitter { private wss:any private connections:WS2PConnection[] = [] - private maxLevel2Size = WS2PConstants.MAX_LEVEL_2_PEERS private constructor( private server:Server, @@ -23,18 +22,13 @@ export class WS2PServer extends events.EventEmitter { private fifo:GlobalFifoPromise, private shouldAcceptConnection:(pubkey:string, connectedPubkeys:string[])=>Promise<boolean>) { super() - // Conf: max public connections - if (this.server.conf.ws2p && this.server.conf.ws2p.maxPublic !== undefined) { - this.maxLevel2Size = this.server.conf.ws2p.maxPublic - } } get maxLevel2Peers() { - return this.maxLevel2Size || 0 - } - - set maxLevel2Peers(newValue:number) { - this.maxLevel2Size = Math.max(newValue, 0) + if (this.server.conf.ws2p && this.server.conf.ws2p.maxPublic !== undefined && this.server.conf.ws2p.maxPublic !== null) { + return this.server.conf.ws2p.maxPublic + } + return WS2PConstants.MAX_LEVEL_2_PEERS } getConnexions() { @@ -132,7 +126,7 @@ export class WS2PServer extends events.EventEmitter { /*** OVERFLOW TRIMMING ***/ let disconnectedOne = true // Disconnect non-members - while (disconnectedOne && this.connections.length > this.maxLevel2Size) { + while (disconnectedOne && this.connections.length > this.maxLevel2Peers) { disconnectedOne = false for (const c of this.connections) { const isMember = await this.server.dal.isMember(c.pubkey) @@ -144,7 +138,7 @@ export class WS2PServer extends events.EventEmitter { } } // Disconnect members - while (this.connections.length > this.maxLevel2Size) { + while (this.connections.length > this.maxLevel2Peers) { for (const c of this.connections) { c.close() this.removeConnection(c) diff --git a/test/integration/ws2p_server_limitations.ts b/test/integration/ws2p_server_limitations.ts index 8130d186258fb6a94f927ad2e0baaf58bbf7f63d..41efe96e9462442a6798b597ffdcc4b0f0047f75 100644 --- a/test/integration/ws2p_server_limitations.ts +++ b/test/integration/ws2p_server_limitations.ts @@ -140,7 +140,7 @@ describe("WS2P server limitations", function() { }) it('should not connect to s3 because of connection size limit', async () => { - cluster3.maxLevel2Peers = 0 + if (s3.conf.ws2p) s3.conf.ws2p.maxPublic = 0 const p3 = await s3.getPeer() await s2.writePeer(p3) b3 = await s1.commit({ time: now }) @@ -164,29 +164,58 @@ describe("WS2P server limitations", function() { }) }) - it('should connect to s3 because of configuration favorism', async () => { - cluster3.maxLevel2Peers = 1 - if (s1._server.conf.ws2p) s1._server.conf.ws2p.privateAccess = true - if (s3._server.conf.ws2p) s3._server.conf.ws2p.publicAccess = true + it('should be able to fully disconnect the WS2P network', async () => { + // Preparation for next test of configuration favorism await s3.writeBlock(b3) - await s3._server.PeeringService.generateSelfPeer(s3._server.conf) - await s3._server.PeeringService.generateSelfPeer(s3._server.conf) await s1.waitToHaveBlock(3) await s2.waitToHaveBlock(3) // await waitForkWS2PConnection(s3._server, 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd') b4 = await s1.commit({ time: now }) await s2.waitToHaveBlock(4) + // The test + if (s3.conf.ws2p) s3.conf.ws2p.maxPublic = 0 + if (s1.conf.ws2p) s1.conf.ws2p.maxPublic = 0 // <-- Breaks the connection s2 -> s1 + await cluster1.trimServerConnections() + await waitForkWS2PDisconnection(s1._server, '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc') + await cluster3.trimServerConnections() + await s1.expect('/network/ws2p/info', (res:any) => { + assert.equal(res.peers.level1, 0) + assert.equal(res.peers.level2, 0) + }) + await s2.expect('/network/ws2p/info', (res:any) => { + assert.equal(res.peers.level1, 0) + assert.equal(res.peers.level2, 0) + }) + await s3.expect('/network/ws2p/info', (res:any) => { + assert.equal(res.peers.level1, 0) + assert.equal(res.peers.level2, 0) + }) + await s4.expect('/network/ws2p/info', (res:any) => { + assert.equal(res.peers.level1, 0) + assert.equal(res.peers.level2, 0) + }) + }) + + it('should connect to s3 because of configuration favorism', async () => { + if (s1._server.conf.ws2p) s1._server.conf.ws2p.privateAccess = true + if (s3._server.conf.ws2p) s3._server.conf.ws2p.publicAccess = true + if (s3._server.conf.ws2p) { + s3._server.conf.ws2p.publicAccess = true + s3._server.conf.ws2p.maxPublic = 1 + } await s3._server.PeeringService.generateSelfPeer(s3._server.conf) const p3 = await s3.getPeer() await s2.writePeer(p3) + await waitForkWS2PConnection(s3._server, '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc') + await s1.writePeer(p3) await waitForkWS2PConnection(s3._server, 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd') - await waitForkWS2PDisconnection(s3._server, '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc') + await waitForkWS2PDisconnection(s3._server, '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc') // <-- s2 is kicked! s1 is prefered await s1.expect('/network/ws2p/info', (res:any) => { assert.equal(res.peers.level1, 1) // <- New connection to s3 - assert.equal(res.peers.level2, 1) + assert.equal(res.peers.level2, 0) }) await s2.expect('/network/ws2p/info', (res:any) => { - assert.equal(res.peers.level1, 1) + assert.equal(res.peers.level1, 0) assert.equal(res.peers.level2, 0) }) await s3.expect('/network/ws2p/info', (res:any) => {