UNPKG

chia-network-scanner

Version:
132 lines 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PeerConnection = void 0; const log_1 = require("./log"); const MessageChannel_1 = require("./MessageChannel"); const encoder_1 = require("./encoder"); class PeerConnection { constructor({ networkId, protocolVersion, softwareVersion, nodeType, hostname, port, connectionTimeout, cert, key }) { this.messageHandlers = new Map(); this.messageChannel = new MessageChannel_1.MessageChannel({ networkId, protocolVersion, softwareVersion, nodeType, hostname, port, connectionTimeout, onMessage: data => this.onMessage(data), cert, key }); } async connect() { return new Promise(async (resolve, reject) => { const timeout = setTimeout(() => reject(new Error('Failed to connect to peer within 2 seconds')), 2000); try { await this.messageChannel.connect(); // Connected within timeout clearTimeout(timeout); resolve(); } catch (err) { clearTimeout(timeout); reject(err); } }); } /** * Chia application level handshake required before using the peer protocol. */ async handshake() { const { hostname, port, connectionTimeout, networkId, protocolVersion, softwareVersion, nodeType } = this.messageChannel; return new Promise(async (resolve, reject) => { const timeout = setTimeout(() => reject(new Error(`${hostname}:${port} did not respond to handshake within ${(connectionTimeout / 1000).toFixed(2)} seconds. Bailing.`)), connectionTimeout); // Handle handshake response messages const handshakeResponse = [ this.expectMessage(encoder_1.ProtocolMessageTypes.handshake), this.expectMessage(encoder_1.ProtocolMessageTypes.handshake_ack) ]; // Initiate handshake this.sendMessage(encoder_1.ProtocolMessageTypes.handshake, { network_id: networkId, protocol_version: protocolVersion, software_version: softwareVersion, server_port: port, node_type: nodeType }); try { // Wait for handshake response await Promise.race(handshakeResponse); } catch (err) { return reject(err); } // Handshake completed within timeout clearTimeout(timeout); // We can now use the peer protocol resolve(this); }); } sendMessage(messageType, data) { const message = encoder_1.encodeMessage(messageType, data); log_1.log.info(`Sending ${messageType} message`); this.messageChannel.sendMessage(message); } /** * Get the peers of this peer. */ getPeers() { const { hostname, port, connectionTimeout } = this.messageChannel; return new Promise((resolve, reject) => { const timeout = setTimeout(() => reject(new Error(`${hostname}:${port} did not respond after ${(connectionTimeout / 1000).toFixed(2)} seconds. Bailing.`)), connectionTimeout); this.addMessageHandler(encoder_1.ProtocolMessageTypes.respond_peers, (respondPeers) => { clearTimeout(timeout); resolve(respondPeers.peer_list); }); this.sendMessage(encoder_1.ProtocolMessageTypes.request_peers, {}); }); } close() { return this.messageChannel.close(); } addMessageHandler(messageType, handler) { log_1.log.debug(`Adding message handler for ${messageType} messages`); this.messageHandlers.set(messageType, handler); } onMessage(data) { try { const messageType = data[0]; log_1.log.info(`Received message of type ${messageType}`); const message = encoder_1.decodeMessage(data); log_1.log.info(`Decoded message to ${JSON.stringify(message)}`); const handler = this.messageHandlers.get(messageType); if (handler) { return handler(message); } log_1.log.warn(`No handler for ${messageType} message. Discarding it.`); } catch (err) { // Anybody could send any old rubbish down the wire and we don't want that to crash our process log_1.log.error(err, 'Error handling inbound message'); log_1.log.warn(`Hex of message that could not be decoded: ${data.toString('hex')}`); } } /** * Expects a message of a messageType to be received within a timeout. * * @param messageType expected */ expectMessage(messageType) { const { hostname, port, connectionTimeout } = this.messageChannel; return new Promise((resolve, reject) => { const timeout = setTimeout(() => reject(new Error(`${hostname}:${port} did not receive ${messageType} message within ${(connectionTimeout / 1000).toFixed(2)} seconds. Bailing.`)), connectionTimeout); this.addMessageHandler(messageType, () => { clearTimeout(timeout); resolve(); }); }); } } exports.PeerConnection = PeerConnection; //# sourceMappingURL=PeerConnection.js.map