chia-network-scanner
Version:
Scans the Chia network for active full nodes
83 lines • 3.42 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageChannel = void 0;
const ws_1 = __importDefault(require("ws"));
const log_1 = require("./log");
class MessageChannel {
constructor({ networkId, protocolVersion, softwareVersion, nodeType, hostname, port, onMessage, connectionTimeout, cert, key }) {
this.ws = null;
this.inboundDataBuffer = Buffer.from([]);
this.networkId = networkId;
this.protocolVersion = protocolVersion;
this.softwareVersion = softwareVersion;
this.nodeType = nodeType;
this.hostname = hostname;
this.port = port;
this.onMessage = onMessage;
this.connectionTimeout = connectionTimeout;
this.cert = cert;
this.key = key;
}
async connect() {
return new Promise(resolve => {
log_1.log.info(`Attempting websocket connection to wss://${this.hostname}:${this.port}/ws`);
const ipv6 = this.hostname.includes(':');
const url = ipv6 ?
`wss://[${this.hostname}]:${this.port}/ws` :
`wss://${this.hostname}:${this.port}/ws`;
this.ws = new ws_1.default(url, {
rejectUnauthorized: false,
cert: this.cert,
key: this.key
});
this.ws.on('message', (data) => this.messageHandler(data));
this.ws.on('error', (err) => this.onClose(err));
this.ws.on('close', (_, reason) => this.onClose(new Error(reason)));
this.ws.on('open', () => {
this.onConnected();
resolve();
});
});
}
sendMessage(message) {
var _a;
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.send(message);
}
close() {
var _a;
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
}
messageHandler(data) {
this.inboundDataBuffer = Buffer.concat([this.inboundDataBuffer, data]);
// Buffer is big enough to contain the length
if (this.inboundDataBuffer.byteLength >= 5) {
const messageType = data[0];
const haveMessageId = data.readUInt8(1);
const messageLength = haveMessageId > 0 ?
data.readUInt32BE(4) :
data.readUInt32BE(2);
const messageReady = data.byteLength === messageLength + 6;
const bufferOverflow = data.byteLength > messageLength + 6;
if (messageReady) {
this.onMessage(this.inboundDataBuffer);
this.inboundDataBuffer = Buffer.from([]);
}
else if (bufferOverflow) {
// Very basic protection against badly developed or malicious peers
// Depending on what they are doing this could happen many times in a row but should eventually recover
this.inboundDataBuffer = Buffer.from([]);
}
}
}
onConnected() {
log_1.log.info(`Established websocket connection to Chia node ${this.hostname}:${this.port}`);
}
onClose(err) {
log_1.log.info(err || {}, 'Connection closed');
}
}
exports.MessageChannel = MessageChannel;
//# sourceMappingURL=MessageChannel.js.map