UNPKG

chia-network-scanner

Version:
134 lines 5.64 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChiaNetworkScanner = void 0; const fs_1 = __importDefault(require("fs")); const async = __importStar(require("async")); const log_1 = require("./log"); const options_1 = require("./options"); const peer_1 = require("./peer"); const PeerConnection_1 = require("./PeerConnection"); class ChiaNetworkScanner { constructor(options) { this.options = options; this.queue = async.queue(this.processPeer.bind(this), this.options.concurrency); this.peers = new Map(); this.scanInProgress = false; this.options = options_1.parseOptions(options); } /** * The scan is started from the full node provided in the options. */ async scan() { if (this.scanInProgress) { throw new Error('Only one scan be be performed at a time'); } log_1.log.info('Starting scan of Chia Network'); // Prevents caller from executing async scan more than once at a time this.scanInProgress = true; const { startNodes } = this.options; // Reset peers from any previous scans this.peers = new Map(); // The network scan is started from passed in start nodes startNodes.forEach(node => { this.queue.push(new peer_1.Peer({ hostname: node.hostname, port: node.port, timestamp: Math.floor(Date.now() / 1000) }), (e) => { console.log(`fin ${node.hostname}:${node.port}`, e); }); }); await this.queue.drain(); // Async network scan has finished, another could now be performed this.scanInProgress = false; return [ ...this.peers.values() ]; } /** * Peers are added to the async queue and a graph traversal of the network is performed. * * The concurrency parameter passed in the constructor specifies how many of these are executed concurrently via the event loop. */ async processPeer(proposedPeer) { const peerLogger = log_1.log.child({ ...proposedPeer }); const ipv6 = proposedPeer.hostname.includes(':'); // Only scan ipv4 because ipv6 nodes can appear with both their ipv4 address and their ipv6 address if (ipv6) { return; } const { connectionTimeout, network, peer: peerOptions, certPath, keyPath } = this.options; const peerHash = proposedPeer.hash(); if (!this.peers.has(peerHash)) { peerLogger.debug('First time seeing peer'); this.peers.set(peerHash, proposedPeer); } // Ensures we get the visited value of peer from previous traversal const peer = this.peers.get(peerHash); // We only visit each peer once if (peer.visited) { peerLogger.debug('Skipping already visited peer'); if (proposedPeer.timestamp > peer.timestamp) { peerLogger.debug(`Updating visited peer to more recent timestamp`); proposedPeer.visit(); this.peers.set(peerHash, proposedPeer); } return; } peerLogger.info('Visiting peer'); // Set to visited immediately to prevent async processing of the same peer peer.visit(); // Opens a websocket connection with the peer we are processing const peerConnection = new PeerConnection_1.PeerConnection({ networkId: network.networkId, protocolVersion: network.protocolVersion, softwareVersion: network.softwareVersion, nodeType: peerOptions.nodeType, hostname: peer.hostname, port: peer.port, connectionTimeout, cert: fs_1.default.readFileSync(certPath), key: fs_1.default.readFileSync(keyPath) }); peerLogger.info('Establishing websocket connection'); try { // Establish websocket connection await peerConnection.connect(); peerLogger.info('Websocket connection established'); // Performs application level handshake with peer await peerConnection.handshake(); const peers = await peerConnection.getPeers(); // Enqueue peers of peer for async processing this.queue.push(peers); // Close websocket connection await peerConnection.close(); } catch (err) { log_1.log.error(err); } } } exports.ChiaNetworkScanner = ChiaNetworkScanner; //# sourceMappingURL=index.js.map