UNPKG

xud

Version:
206 lines 9.67 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 (Object.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 }); /* tslint:disable brace-style */ const events_1 = require("events"); const errors_1 = __importDefault(require("./errors")); const Framer_1 = __importDefault(require("./Framer")); const packets_1 = require("./packets"); const Packet_1 = require("./packets/Packet"); const packetTypes = __importStar(require("./packets/types")); /** Wire protocol msg parser */ let Parser = /** @class */ (() => { class Parser extends events_1.EventEmitter { constructor(framer, msgHeaderLength = Framer_1.default.MSG_HEADER_LENGTH, maxBufferSize = Parser.MAX_BUFFER_SIZE) { super(); this.framer = framer; this.msgHeaderLength = msgHeaderLength; this.maxBufferSize = maxBufferSize; this.pending = []; this.waiting = 0; this.waitingHeader = 0; this.setEncryptionKey = (key) => { this.encryptionKey = key; this.msgHeaderLength = Framer_1.default.ENCRYPTED_MSG_HEADER_LENGTH; }; this.feed = (chunk) => { // verify that total size isn't exceeding const totalSize = this.getTotalSize(chunk); if (totalSize > this.maxBufferSize) { this.error(errors_1.default.PARSER_MAX_BUFFER_SIZE_EXCEEDED(totalSize)); return; } // reading through a split message if (this.waiting) { this.read(this.waiting, chunk); } // reading through a message which is split on the header else if (this.waitingHeader) { this.pending.push(chunk); const data = Buffer.concat(this.pending); const length = this.parseLength(data); if (!length) { return; } this.pending = []; this.read(length + this.msgHeaderLength, data); } // starting to read a new message which is split on the header else if (chunk.length < this.msgHeaderLength) { this.pending.push(chunk); this.waitingHeader = this.msgHeaderLength - chunk.length; } // starting to read a new message else { const length = this.parseLength(chunk); if (!length) { return; } this.read(length + this.msgHeaderLength, chunk); } }; this.read = (length, chunk) => { this.pending.push(chunk.slice(0, length)); // message isn't complete if (length > chunk.length) { this.waiting = length - chunk.length; } // chunk is finalizing the msg else { this.parseMessage(this.pending); this.resetBuffer(); // chunk is containing more messages if (length < chunk.length) { this.feed(chunk.slice(length)); } } }; this.getTotalSize = (chunk) => { const current = this.pending .map(buffer => buffer.length) .reduce((acc, curr) => acc + curr, 0); return current + chunk.length; }; this.resetBuffer = () => { this.waiting = 0; this.waitingHeader = 0; this.pending = []; }; this.parseLength = (data) => { try { return this.framer.parseLength(data, !!this.encryptionKey); } catch (err) { this.error(err); return 0; } }; this.parseMessage = (chunks) => { try { const msg = Buffer.concat(chunks); const { header, packet } = this.framer.unframe(msg, this.encryptionKey); const parsedPacket = this.parsePacket(header, Uint8Array.from(packet)); this.emit('packet', parsedPacket); } catch (err) { this.error(err); } }; this.parsePacket = (header, payload) => { let packetOrPbObj; switch (header.type) { case packets_1.PacketType.SessionInit: packetOrPbObj = packetTypes.SessionInitPacket.deserialize(payload); break; case packets_1.PacketType.SessionAck: packetOrPbObj = packetTypes.SessionAckPacket.deserialize(payload); break; case packets_1.PacketType.NodeStateUpdate: packetOrPbObj = packetTypes.NodeStateUpdatePacket.deserialize(payload); break; case packets_1.PacketType.Disconnecting: packetOrPbObj = packetTypes.DisconnectingPacket.deserialize(payload); break; case packets_1.PacketType.Ping: packetOrPbObj = packetTypes.PingPacket.deserialize(payload); break; case packets_1.PacketType.Pong: packetOrPbObj = packetTypes.PongPacket.deserialize(payload); break; case packets_1.PacketType.Order: packetOrPbObj = packetTypes.OrderPacket.deserialize(payload); break; case packets_1.PacketType.OrderInvalidation: packetOrPbObj = packetTypes.OrderInvalidationPacket.deserialize(payload); break; case packets_1.PacketType.GetOrders: packetOrPbObj = packetTypes.GetOrdersPacket.deserialize(payload); break; case packets_1.PacketType.Orders: packetOrPbObj = packetTypes.OrdersPacket.deserialize(payload); break; case packets_1.PacketType.GetNodes: packetOrPbObj = packetTypes.GetNodesPacket.deserialize(payload); break; case packets_1.PacketType.Nodes: packetOrPbObj = packetTypes.NodesPacket.deserialize(payload); break; case packets_1.PacketType.SanitySwap: packetOrPbObj = packetTypes.SanitySwapInitPacket.deserialize(payload); break; case packets_1.PacketType.SanitySwapAck: packetOrPbObj = packetTypes.SanitySwapAckPacket.deserialize(payload); break; case packets_1.PacketType.SwapRequest: packetOrPbObj = packetTypes.SwapRequestPacket.deserialize(payload); break; case packets_1.PacketType.SwapAccepted: packetOrPbObj = packetTypes.SwapAcceptedPacket.deserialize(payload); break; case packets_1.PacketType.SwapFailed: packetOrPbObj = packetTypes.SwapFailedPacket.deserialize(payload); break; default: throw errors_1.default.PARSER_UNKNOWN_PACKET_TYPE(header.type.toString()); } if (!Packet_1.isPacket(packetOrPbObj)) { throw errors_1.default.PARSER_INVALID_PACKET(`${packets_1.PacketType[header.type]} ${JSON.stringify(packetOrPbObj)}`); } const packet = packetOrPbObj; if (header.checksum && header.checksum !== packet.checksum()) { throw errors_1.default.PARSER_DATA_INTEGRITY_ERR(`${packets_1.PacketType[header.type]} ${JSON.stringify(packet)}`); } return packet; }; this.error = (err) => { this.emit('error', err); this.resetBuffer(); }; } } Parser.MAX_BUFFER_SIZE = (4 * 1024 * 1024); // in bytes return Parser; })(); exports.default = Parser; //# sourceMappingURL=Parser.js.map