From 1bf4910ec77fd28fd7678c43b48009aebed9cb65 Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Thu, 7 Sep 2017 17:36:00 +0200
Subject: [PATCH] [enh] #1084 WS2P: move the wrong endpoint detection in
 modules definition

---
 app/modules/bma/index.ts      | 22 ++++++++++++++++++++++
 app/modules/ws2p/index.ts     |  8 ++++++++
 app/service/PeeringService.ts | 30 +++++++-----------------------
 server.ts                     | 14 ++++++++++++++
 4 files changed, 51 insertions(+), 23 deletions(-)

diff --git a/app/modules/bma/index.ts b/app/modules/bma/index.ts
index f3d1f6cf2..7404240a0 100644
--- a/app/modules/bma/index.ts
+++ b/app/modules/bma/index.ts
@@ -6,9 +6,11 @@ import {BmaApi, Network} from "./lib/network"
 import {UpnpApi} from "./lib/upnp"
 import {BMAConstants} from "./lib/constants"
 import {BMALimitation} from "./lib/limiter"
+import {PeerDTO} from "../../lib/dto/PeerDTO"
 
 const Q = require('q');
 const os = require('os');
+const rp = require('request-promise');
 const async = require('async');
 const _ = require('underscore');
 const upnp = require('./lib/upnp').Upnp
@@ -139,6 +141,7 @@ export const BmaDependency = {
     service: {
       input: (server:Server, conf:NetworkConfDTO, logger:any) => {
         server.addEndpointsDefinitions(() => Promise.resolve(getEndpoint(conf)))
+        server.addWrongEndpointFilter((endpoints:string[]) => getWrongEndpoints(endpoints, server.conf.pair.pub))
         return new BMAPI(server, conf, logger)
       }
     },
@@ -151,6 +154,25 @@ export const BmaDependency = {
   }
 }
 
+async function getWrongEndpoints(endpoints:string[], selfPubkey:string) {
+  const wrongs:string[] = []
+  await Promise.all(endpoints.map(async (theEndpoint:string) => {
+    let remote = PeerDTO.endpoint2host(theEndpoint)
+    try {
+      // We test only BMA APIs, because other may exist and we cannot judge against them
+      if (theEndpoint.startsWith('BASIC_MERKLED_API')) {
+        let answer = await rp('http://' + remote + '/network/peering', { json: true });
+        if (!answer || answer.pubkey != selfPubkey) {
+          throw Error("Not same pubkey as local instance");
+        }
+      }
+    } catch (e) {
+      wrongs.push(theEndpoint)
+    }
+  }))
+  return wrongs
+}
+
 export class BMAPI extends stream.Transform {
 
   // Public http interface
diff --git a/app/modules/ws2p/index.ts b/app/modules/ws2p/index.ts
index 97025e0dd..aedf27ec5 100644
--- a/app/modules/ws2p/index.ts
+++ b/app/modules/ws2p/index.ts
@@ -48,12 +48,20 @@ export const WS2PDependency = {
       input: (server:Server, conf:WS2PConfDTO, logger:any) => {
         const api = new WS2PAPI(server, conf, logger)
         server.addEndpointsDefinitions(() => api.getEndpoint())
+        server.addWrongEndpointFilter((endpoints:string[]) => getWrongEndpoints(endpoints, conf))
         return api
       }
     }
   }
 }
 
+async function getWrongEndpoints(endpoints:string[], ws2pConf:WS2PConfDTO) {
+  return endpoints.filter(ep => {
+    const match = ep.match(CommonConstants.WS2P_REGEXP)
+    return ws2pConf.ws2p && match && match[1] === ws2pConf.ws2p.uuid
+  })
+}
+
 export class WS2PAPI extends stream.Transform {
 
   // Public http interface
diff --git a/app/service/PeeringService.ts b/app/service/PeeringService.ts
index 8ac5db837..0335900b5 100644
--- a/app/service/PeeringService.ts
+++ b/app/service/PeeringService.ts
@@ -9,11 +9,11 @@ import {dos2unix} from "../lib/common-libs/dos2unix"
 import {rawer} from "../lib/common-libs/index"
 import {Server} from "../../server"
 import {GlobalFifoPromise} from "./GlobalFifoPromise"
+import {server} from "../../test/integration/tools/toolbox"
 
 const util           = require('util');
 const _              = require('underscore');
 const events         = require('events');
-const rp             = require('request-promise');
 const logger         = require('../lib/logger').NewLogger('peering');
 const constants      = require('../lib/constants');
 
@@ -199,28 +199,12 @@ export class PeeringService {
     const localEndpoints = await this.server.getEndpoints()
     const otherPotentialEndpoints = this.getOtherEndpoints(p1.endpoints, localEndpoints)
     logger.info('Sibling endpoints:', otherPotentialEndpoints);
-    let reals = await Promise.all(otherPotentialEndpoints.map(async (theEndpoint:string) => {
-      let real = true;
-      let remote = PeerDTO.endpoint2host(theEndpoint)
-      try {
-        // We test only BMA APIs, because other may exist and we cannot judge against them yet
-        if (theEndpoint.startsWith('BASIC_MERKLED_API')) {
-          let answer = await rp('http://' + remote + '/network/peering', { json: true });
-          if (!answer || answer.pubkey != this.selfPubkey) {
-            throw Error("Not same pubkey as local instance");
-          }
-        }
-        // We also remove endpoints this are *asked* to be removed in the conf file
-        if ((this.conf.rmEndpoints || []).indexOf(theEndpoint) !== -1) {
-          real = false;
-        }
-      } catch (e) {
-        logger.warn('Wrong endpoint \'%s\': \'%s\'', theEndpoint, e.message || e);
-        real = false;
-      }
-      return real;
-    }))
-    let toConserve = otherPotentialEndpoints.filter((ep, i) => reals[i]);
+    const wrongEndpoints = await this.server.getWrongEndpoints(otherPotentialEndpoints)
+    for (const wrong of wrongEndpoints) {
+      logger.warn('Wrong endpoint \'%s\'', wrong)
+    }
+    const toRemoveByConf = (this.conf.rmEndpoints || [])
+    let toConserve = otherPotentialEndpoints.filter(ep => wrongEndpoints.indexOf(ep) === -1 && toRemoveByConf.indexOf(ep) === -1)
     if (!currency) {
       logger.error('It seems there is an issue with your configuration.');
       logger.error('Please restart your node with:');
diff --git a/server.ts b/server.ts
index 5b1832de2..b012cd4ee 100644
--- a/server.ts
+++ b/server.ts
@@ -47,6 +47,7 @@ export class Server extends stream.Duplex implements HookableServer {
 
   private paramsP:Promise<any>|null
   private endpointsDefinitions:(()=>Promise<string>)[] = []
+  private wrongEndpointsFilters:((endpoints:string[])=>Promise<string[]>)[] = []
   conf:ConfDTO
   dal:FileDAL
 
@@ -569,11 +570,24 @@ export class Server extends stream.Duplex implements HookableServer {
     this.endpointsDefinitions.push(definition)
   }
 
+  addWrongEndpointFilter(filter:(endpoints:string[])=>Promise<string[]>) {
+    this.wrongEndpointsFilters.push(filter)
+  }
+
   async getEndpoints() {
     const endpoints = await Promise.all(this.endpointsDefinitions.map(d => d()))
     return endpoints.filter(ep => !!ep)
   }
 
+  async getWrongEndpoints(endpoints:string[]) {
+    let wrongs:string[] = []
+    for (const filter of this.wrongEndpointsFilters) {
+      const newWrongs = await filter(endpoints)
+      wrongs = wrongs.concat(newWrongs)
+    }
+    return wrongs
+  }
+
   /*****************
    * MODULES PLUGS
    ****************/
-- 
GitLab