UNPKG

ntrnetwork

Version:

Transledger peer to peer wire communication

170 lines (154 loc) 6.3 kB
// LIBRARIES IMPORTS // ===================================================================== const DPT = require('./dpt'); const RLPx = require('./rlpx'); const _util = require('./util'); const NTR = require('./interblockchain'); //const LRUCache = require('lru-cache'); const assert = require('assert'); const { randomBytes } = require('crypto'); //const rlp = require('rlp-encoding'); const nodes = require('../src/environment').peers; const environment = require('../src/environment'); const getPeerAddr = (peer) => `${peer._socket.remoteAddress}:${peer._socket.remotePort}`; //const getPeerIP = (peer) => `${peer._socket.remoteAddress}`; const debug = process.env.MONITOR || require('./environment').debug.monitor; // EXPORT STATUS OBJECT // ====================================================================== const status = { networkId: 1, networkName: "interblockchain", Note:"test in progress", nodeID: environment.nodeID } // GLOBALS INITIALIZATION // ====================================================================== const PRIVATE_KEY = randomBytes(32); const REMOTE_CLIENTID_FILTER = ['interblockchain']; // DPT INSTANCE CREATION // ===================================================================== // We create a Distributed Peer Table (DPT) // and set an error handler. The table is refreshed // every 30 seconds const dpt = new DPT(PRIVATE_KEY, { refreshInterval: 180000, endpoint: { address: '0.0.0.0', udpPort: null, tcpPort: null } }) dpt.on('error', (err) => { if (err.message.match(/Timeout/)) { debug ? console.error(`${Date().toString().substring(0, 24)} monitor: DPT error: ${err}`) : null; } else { console.error(`${Date().toString().substring(0, 24)} monitor: DPT error: ${err}`); } }); dpt.server.monitor = true; // RLPX INSTANCE CREATION // ============================================================================ // We create a RLPX object and an error handler. // The RLPX protocol is based on the Kamdelia protocol. // This instance uses a DLT table and the interblockchain // protocol. We set the limit to 7 peers const rlpx = new RLPx(PRIVATE_KEY, { dpt: dpt, maxPeers: environment.maxPeers, capabilities: [ NTR.ntr ], remoteClientIdFilter: REMOTE_CLIENTID_FILTER, listenPort: null }) rlpx.on('error', (err) => { if (err.message.match(/Timeout|valid tag/)) { debug ? console.error(`${Date().toString().substring(0, 24)} monitor: RLPx error: ${err.stack || err}`) : null; } else { console.error(`${Date().toString().substring(0, 24)} monitor: RLPx error: ${err.stack || err}`); } }); rlpx.on('close', (reason) => { a = reason; }); rlpx.monitor = true; // Node listening comands dpt.bind(environment.port, '0.0.0.0'); rlpx.listen(environment.port, '0.0.0.0'); console.log (`server version: ${environment.version} with nodeID: ${environment.nodeID} listening to socket on port 20399`); // CONNECT TO BOOTSTRAP NODES // =============================================================================== // the bootstrap nodes are declared in the environment/index.js file // Each bootstrap node is declared as an object contained into an container object. // Initially, that collection of bootstrap node objects is scanned to connect // the present node to the network. setTimeout( () => { let BOOTNODES = []; /* To be deleted const BOOTNODES = nodes.filter((node) => { return node.channelID === rlpx.channelID; }).map((node) => { return { address: node.ip, udpPort: node.port, tcpPort: node.port } }); */ nodes.forEach( (node) => { BOOTNODES.push({ channelID: node.channelID, address: node.ip, udpPort: node.port, tcpPort: node.port }) }); for (let bootnode of BOOTNODES) { dpt.bootstrap(bootnode).catch((err) => { if (err.message.match(/Timeout|valid tag/)) console.error(`${Date().toString().substring(0, 24)} monitor: DPT bootstrap ${err}`); else console.error(`${Date().toString().substring(0, 24)} monitor: DPT bootstrap ${err.stack || err}`); }) } },500); // RLPX ERROR HANDLING // =========================================================================== // rlpx errors are bubbled up to these error handlers // When a node is disconnected, an event is fired and bubbled up to // the event handler. rlpx.on('peer:removed', (peer, reasonCode, disconnectWe) => { const who = disconnectWe ? 'we disconnect' : 'peer disconnect'; const total = rlpx.getPeers().length; console.log(`${Date().toString().substring(0, 24)} monitor: Remove peer: ${getPeerAddr(peer)} - ${who}, reason: ${peer.getDisconnectPrefix(reasonCode)} (${String(reasonCode)}) (total: ${total})`); }) rlpx.on('peer:error', (peer, err) => { if (err.code === 'ECONNRESET') return if (err instanceof assert.AssertionError) { const peerId = peer.getId() if (peerId !== null) dpt.banPeer(peerId, 5000); debug ? console.error(`${Date().toString().substring(0, 24)} monitor: Peer error (${getPeerAddr(peer)}): ${err.message}`) : null; return } console.error(`${Date().toString().substring(0, 24)} monitor: Peer error (${getPeerAddr(peer)}): ${err.stack || err}`); }); // DPT STATUS // ============================================================================= setInterval( () => { const peersCount = dpt.getPeers().length; const openSlots = rlpx._getOpenSlots(); const queueLength = rlpx._peersQueue.length; const queueLength2 = rlpx._peersQueue.filter((o) => o.ts <= Date.now()).length; //console.log(`${Date().toString().substring(0, 24)} monitor: Total nodes in DPT: ${peersCount}, open slots: ${openSlots}, queue: ${queueLength} / ${queueLength2}`); },180000); // EXPORTS FROM THIS LIBRARY // ================================================================================ exports.DPT = DPT; exports.RLPx = RLPx; exports._util = _util; exports.NTR = NTR; exports.rlpx = rlpx; exports.dpt = dpt; exports.MESSAGE_CODES = NTR.MESSAGE_CODES; exports.status = status;