diff --git a/lib/Config.ts b/lib/Config.ts index bc95d99d3..164ed202c 100644 --- a/lib/Config.ts +++ b/lib/Config.ts @@ -6,7 +6,7 @@ import { exists, mkdir, readFile } from './utils/fsUtils'; import { LndClientConfig } from './lndclient/LndClient'; import { RaidenClientConfig } from './raidenclient/RaidenClient'; import { Level } from './Logger'; -import { Network } from './types/enums'; +import { Network, NetworkMagic } from './types/enums'; import { PoolConfig } from './types/p2p'; class Config { diff --git a/lib/Xud.ts b/lib/Xud.ts index 4d92c9835..bc0def5b4 100644 --- a/lib/Xud.ts +++ b/lib/Xud.ts @@ -108,7 +108,7 @@ class Xud extends EventEmitter { raidenAddress: this.raidenClient.address, lndbtcPubKey: this.lndbtcClient.pubKey, lndltcPubKey: this.lndltcClient.pubKey, - }); + }, this.nodeKey); this.service = new Service(loggers.global, { version, @@ -164,12 +164,12 @@ class Xud extends EventEmitter { private bind = () => { this.lndbtcClient.on('connectionVerified', (newPubKey) => { if (newPubKey) { - this.pool.updateHandshake({ lndbtcPubKey: newPubKey }); + this.pool.updateNodeState({ lndbtcPubKey: newPubKey }); } }); this.lndltcClient.on('connectionVerified', (newPubKey) => { if (newPubKey) { - this.pool.updateHandshake({ lndltcPubKey: newPubKey }); + this.pool.updateNodeState({ lndltcPubKey: newPubKey }); } }); } diff --git a/lib/nodekey/NodeKey.ts b/lib/nodekey/NodeKey.ts index 5a7d7b6b0..ee2ec2ecf 100644 --- a/lib/nodekey/NodeKey.ts +++ b/lib/nodekey/NodeKey.ts @@ -19,6 +19,10 @@ class NodeKey { return this.pubKeyStr; } + public get nodePrivKey(): Buffer { + return this.privKey; + } + /** * Generates a random NodeKey. */ diff --git a/lib/orderbook/OrderBook.ts b/lib/orderbook/OrderBook.ts index 05f87118f..7be8fcb83 100644 --- a/lib/orderbook/OrderBook.ts +++ b/lib/orderbook/OrderBook.ts @@ -196,7 +196,7 @@ class OrderBook extends EventEmitter { this.tradingPairs.set(pairInstance.id, new TradingPair(this.logger, pairInstance.id, this.nomatching)); if (this.pool) { - this.pool.updateHandshake({ pairs: this.pairIds }); + this.pool.updateNodeState({ pairs: this.pairIds }); } return pairInstance; } @@ -234,7 +234,7 @@ class OrderBook extends EventEmitter { this.tradingPairs.delete(pairId); if (this.pool) { - this.pool.updateHandshake({ pairs: this.pairIds }); + this.pool.updateNodeState({ pairs: this.pairIds }); } return pair.destroy(); } diff --git a/lib/p2p/Framer.ts b/lib/p2p/Framer.ts new file mode 100644 index 000000000..c81f6e40d --- /dev/null +++ b/lib/p2p/Framer.ts @@ -0,0 +1,183 @@ +import assert from 'assert'; +import crypto from 'crypto'; +import Network from './Network'; +import Packet from './packets/Packet'; +import errors from './errors'; + +type WireMsgHeader = { + magic?: number, + type: number, + length: number, + checksum?: number, +}; + +type WireMsg = { + header: WireMsgHeader, + packet: Buffer; +}; + +/** Wire protocol msg framer */ +class Framer { + public static readonly MSG_HEADER_LENGTH = 16; + public static readonly ENCRYPTED_MSG_HEADER_LENGTH = 4; + public static readonly ENCRYPTED_MSG_PAYLOAD_HEADER_LENGTH = 8; + public static readonly ENCRYPTION_KEY_LENGTH = 32; + public static readonly ENCRYPTION_IV_LENGTH = 16; + + constructor(private network: Network) { + } + + /** + * Frame a packet with a header to be used as a wire msg + */ + public frame = (packet: Packet, encryptionKey?: Buffer): Buffer => { + const packetRaw = packet.toRaw(); + + if (encryptionKey) { + const msg = Buffer.allocUnsafe(Framer.ENCRYPTED_MSG_PAYLOAD_HEADER_LENGTH + packetRaw.length); + + // length + msg.writeUInt32LE(packetRaw.length, 0, true); + + // type + msg.writeUInt32LE(packet.type, 4, true); + + // packet + packetRaw.copy(msg, 8); + + const ciphertext = this.encrypt(msg, encryptionKey); + const encryptedMsg = Buffer.allocUnsafe(Framer.ENCRYPTED_MSG_HEADER_LENGTH + ciphertext.length); + + // length + encryptedMsg.writeUInt32LE(ciphertext.length, 0, true); + + // ciphertext + ciphertext.copy(encryptedMsg, 4); + + return encryptedMsg; + } else { + const msg = Buffer.allocUnsafe(Framer.MSG_HEADER_LENGTH + packetRaw.length); + + // network magic value + msg.writeUInt32LE(this.network.magic, 0, true); + + // length + msg.writeUInt32LE(packetRaw.length, 4, true); + + // type + msg.writeUInt32LE(packet.type, 8, true); + + // checksum + msg.writeUInt32LE(packet.checksum(), 12); + + // payload + packetRaw.copy(msg, 16); + + return msg; + } + } + + /** + * Unframe a wire msg or an encrypted wire msg + */ + public unframe = (msg: Buffer, encryptionKey?: Buffer): WireMsg => { + let wireMsg: WireMsg; + if (encryptionKey) { + const length = msg.readUInt32LE(0, true); + const ciphertext = msg.slice(Framer.ENCRYPTED_MSG_HEADER_LENGTH); + + if (length !== ciphertext.length) { + throw errors.FRAMER_INVALID_MSG_LENGTH(length, ciphertext.length); + } + + const decryptedMsg = this.decrypt(ciphertext, encryptionKey); + + wireMsg = { + header: this.parseHeader(decryptedMsg, true), + packet: decryptedMsg.slice(Framer.ENCRYPTED_MSG_PAYLOAD_HEADER_LENGTH), + }; + } else { + wireMsg = { + header: this.parseHeader(msg, false), + packet: msg.slice(Framer.MSG_HEADER_LENGTH), + }; + } + + if (wireMsg.header.length !== wireMsg.packet.length) { + throw errors.FRAMER_INVALID_MSG_LENGTH(wireMsg.header.length, wireMsg.packet.length); + } + + return wireMsg; + } + + /** + * Parse the length of a wire msg or an encrypted wire msg + */ + public parseLength = (data: Buffer, encrypted: boolean): number => { + const value = data.readUInt32LE(0, true); + + if (encrypted) { + if (value === this.network.magic) { + throw errors.FRAMER_MSG_NOT_ENCRYPTED; + } + return value; + } + + if (value !== this.network.magic) { + throw errors.FRAMER_INVALID_NETWORK_MAGIC_VALUE; + } + + return data.readUInt32LE(4, true); + } + + /** + * Parse the header of a wire msg or an encrypted wire msg payload + */ + public parseHeader = (msg: Buffer, encrypted: boolean): WireMsgHeader => { + if (encrypted) { + assert(msg.length >= Framer.ENCRYPTED_MSG_PAYLOAD_HEADER_LENGTH, `invalid msg header length: data is missing`); + + // length + const length = msg.readUInt32LE(0, true); + + // type + const type = msg.readUInt32LE(4, true); + + return { length, type }; + } else { + assert(msg.length >= Framer.MSG_HEADER_LENGTH, `invalid msg header length: data is missing`); + + // network magic value + const magic = msg.readUInt32LE(0, true); + + // length + const length = msg.readUInt32LE(4, true); + + // type + const type = msg.readUInt32LE(8, true); + + // checksum + const checksum = msg.readUInt32LE(12, true); + + return { magic, type, length, checksum }; + } + } + + public encrypt = (plaintext: Buffer, key: Buffer): Buffer => { + const iv = crypto.randomBytes(Framer.ENCRYPTION_IV_LENGTH); + const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); + + return Buffer.concat([iv, cipher.update(plaintext), cipher.final()]); + } + + public decrypt = (ciphertext: Buffer, key: Buffer): Buffer => { + const iv = ciphertext.slice(0, Framer.ENCRYPTION_IV_LENGTH); + const encrypted = ciphertext.slice(Framer.ENCRYPTION_IV_LENGTH); + const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); + + return Buffer.concat([decipher.update(encrypted), decipher.final()]); + } +} + +export default Framer; +export { WireMsgHeader }; diff --git a/lib/p2p/Network.ts b/lib/p2p/Network.ts new file mode 100644 index 000000000..37c2c28c1 --- /dev/null +++ b/lib/p2p/Network.ts @@ -0,0 +1,7 @@ + +class Network { + constructor(public magic: number) { + } +} + +export default Network; diff --git a/lib/p2p/NodeList.ts b/lib/p2p/NodeList.ts index fe9279ae4..41d3bcdc5 100644 --- a/lib/p2p/NodeList.ts +++ b/lib/p2p/NodeList.ts @@ -12,10 +12,8 @@ export const reputationEventWeight = { [ReputationEvent.PacketTimeout]: -1, [ReputationEvent.SwapFailure]: -10, [ReputationEvent.SwapSuccess]: 1, - [ReputationEvent.InvalidPacket]: -10, - [ReputationEvent.UnknownPacketType]: -20, - [ReputationEvent.PacketDataIntegrityError]: -20, - [ReputationEvent.MaxParserBufferSizeExceeded]: -20, + [ReputationEvent.WireProtocolErr]: -5, + [ReputationEvent.InvalidAuth]: -20, }; // TODO: inform node about getting banned diff --git a/lib/p2p/Parser.ts b/lib/p2p/Parser.ts index 9733bda60..b1ab9a1b7 100644 --- a/lib/p2p/Parser.ts +++ b/lib/p2p/Parser.ts @@ -1,170 +1,205 @@ +/* tslint:disable brace-style */ import { EventEmitter } from 'events'; import { PacketType } from './packets'; import Packet, { isPacket } from './packets/Packet'; import * as packetTypes from './packets/types'; - -class ParserError { - constructor(public type: ParserErrorType, public payload: string) { } -} - -enum ParserErrorType { - InvalidPacket, - UnknownPacketType, - DataIntegrityError, - MaxBufferSizeExceeded, -} - -const fromRaw = (type: number, binary: Uint8Array): Packet => { - let packetOrPbObj; - switch (type) { - case PacketType.Hello: - packetOrPbObj = packetTypes.HelloPacket.deserialize(binary); - break; - case PacketType.Disconnecting: - packetOrPbObj = packetTypes.DisconnectingPacket.deserialize(binary); - break; - case PacketType.Ping: - packetOrPbObj = packetTypes.PingPacket.deserialize(binary); - break; - case PacketType.Pong: - packetOrPbObj = packetTypes.PongPacket.deserialize(binary); - break; - case PacketType.Order: - packetOrPbObj = packetTypes.OrderPacket.deserialize(binary); - break; - case PacketType.OrderInvalidation: - packetOrPbObj = packetTypes.OrderInvalidationPacket.deserialize(binary); - break; - case PacketType.GetOrders: - packetOrPbObj = packetTypes.GetOrdersPacket.deserialize(binary); - break; - case PacketType.Orders: - packetOrPbObj = packetTypes.OrdersPacket.deserialize(binary); - break; - case PacketType.GetNodes: - packetOrPbObj = packetTypes.GetNodesPacket.deserialize(binary); - break; - case PacketType.Nodes: - packetOrPbObj = packetTypes.NodesPacket.deserialize(binary); - break; - case PacketType.SwapRequest: - packetOrPbObj = packetTypes.SwapRequestPacket.deserialize(binary); - break; - case PacketType.SwapAccepted: - packetOrPbObj = packetTypes.SwapAcceptedPacket.deserialize(binary); - break; - case PacketType.SwapComplete: - packetOrPbObj = packetTypes.SwapCompletePacket.deserialize(binary); - break; - case PacketType.SwapFailed: - packetOrPbObj = packetTypes.SwapFailedPacket.deserialize(binary); - break; - default: - throw new ParserError(ParserErrorType.UnknownPacketType, PacketType[type]); - } - - if (!isPacket(packetOrPbObj)) { - throw new ParserError(ParserErrorType.InvalidPacket, `${PacketType[type]} ${JSON.stringify(packetOrPbObj)}`); - } - - const packet = packetOrPbObj; - if (!packet.verifyDataIntegrity()) { - throw new ParserError(ParserErrorType.DataIntegrityError, `${PacketType[type]} ${JSON.stringify(packet)}`); - } - - return packet; -}; +import Framer, { WireMsgHeader } from './Framer'; +import errors from './errors'; interface Parser { on(event: 'packet', packet: (order: Packet) => void): this; - on(event: 'error', err: (order: ParserError) => void): this; + on(event: 'error', err: (order: {message: string, code: string}) => void): this; emit(event: 'packet', packet: Packet): boolean; - emit(event: 'error', err: ParserError): boolean; + emit(event: 'error', err: {message: string, code: string}): boolean; } -/** Protocol packet parser */ +/** Wire protocol msg parser */ class Parser extends EventEmitter { - - public static readonly PACKET_METADATA_SIZE = 5; // in bytes private pending: Buffer[] = []; private waiting = 0; - private waitingMetadata = 0; - private type = 0; + private waitingHeader = 0; + private encryptionKey?: Buffer; private static readonly MAX_BUFFER_SIZE = (4 * 1024 * 1024); // in bytes - constructor(private packetMetadataSize: number = Parser.PACKET_METADATA_SIZE, private maxBufferSize: number = Parser.MAX_BUFFER_SIZE) { + constructor( + private framer: Framer, + private msgHeaderLength: number = Framer.MSG_HEADER_LENGTH, + private maxBufferSize: number = Parser.MAX_BUFFER_SIZE, + ) { super(); } - public feed = (data: Buffer): void => { - const totalSize = this.pending - .map(buffer => buffer.length) - .reduce((acc, curr) => acc + curr, 0) + data.length; + public setEncryptionKey = (key: Buffer) => { + this.encryptionKey = key; + this.msgHeaderLength = Framer.ENCRYPTED_MSG_HEADER_LENGTH; + } + + public feed = (chunk: Buffer): void => { + // verify that total size isn't exceeding + const totalSize = this.getTotalSize(chunk); if (totalSize > this.maxBufferSize) { - this.resetCycle(); - this.emit('error', new ParserError(ParserErrorType.MaxBufferSizeExceeded, totalSize.toString())); + this.error(errors.PARSER_MAX_BUFFER_SIZE_EXCEEDED(totalSize)); return; } + // reading through a split message if (this.waiting) { - this.read(this.waiting, data); - } else if (this.waitingMetadata) { - this.pending.push(data.slice(0, this.waitingMetadata)); - const { type, size } = this.readMetadata(Buffer.concat(this.pending)); - this.type = type; + 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(size, data.slice(this.waitingMetadata)); - } else if (data.length < this.packetMetadataSize) { - this.pending.push(data); - this.waitingMetadata = this.packetMetadataSize - data.length; - } else { - const { type, size } = this.readMetadata(data); - this.type = type; - this.read(size, data.slice(this.packetMetadataSize)); + this.read(length + this.msgHeaderLength, data); } - } - private readMetadata = (data: Buffer): { type: number, size: number } => { - // first byte is the packet type - const type = data.readUInt8(0, true); - // next 4 bytes are the size of the packet - const size = data.readUInt32LE(1, true); + // 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; + } - return { type, size }; + // starting to read a new message + else { + const length = this.parseLength(chunk); + if (!length) { + return; + } + this.read(length + this.msgHeaderLength, chunk); + } } - private read = (size: number, chunk: Buffer) => { - this.pending.push(chunk.slice(0, size)); + private read = (length: number, chunk: Buffer) => { + this.pending.push(chunk.slice(0, length)); - if (size > chunk.length) { // packet isn't complete - this.waiting = size - chunk.length; - } else { // chunk is finalizing the packet - this.parsePacket(this.type, this.pending); - this.resetCycle(); - if (size < chunk.length) { // multiple packets - this.feed(chunk.slice(size)); + // 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)); } } } - private resetCycle = () => { + private getTotalSize = (chunk: Buffer): number => { + const current = this.pending + .map(buffer => buffer.length) + .reduce((acc, curr) => acc + curr, 0); + + return current + chunk.length; + } + + private resetBuffer = () => { this.waiting = 0; - this.waitingMetadata = 0; + this.waitingHeader = 0; this.pending = []; } - private parsePacket = (type: number, chunks: Buffer[]): void => { + private parseLength = (data: Buffer): number => { try { - const buffer = Buffer.concat(chunks); - const binary = Uint8Array.from(buffer); + return this.framer.parseLength(data, !!this.encryptionKey); + } catch (err) { + this.error(err); + return 0; + } + } - const packet = fromRaw(type, binary); - this.emit('packet', packet); + private parseMessage = (chunks: Buffer[]): void => { + 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.emit('error', err); + this.error(err); } } + + private parsePacket = (header: WireMsgHeader, payload: Uint8Array): Packet => { + let packetOrPbObj; + switch (header.type) { + case PacketType.SessionInit: + packetOrPbObj = packetTypes.SessionInitPacket.deserialize(payload); + break; + case PacketType.SessionAck: + packetOrPbObj = packetTypes.SessionAckPacket.deserialize(payload); + break; + case PacketType.NodeStateUpdate: + packetOrPbObj = packetTypes.NodeStateUpdatePacket.deserialize(payload); + break; + case PacketType.Disconnecting: + packetOrPbObj = packetTypes.DisconnectingPacket.deserialize(payload); + break; + case PacketType.Ping: + packetOrPbObj = packetTypes.PingPacket.deserialize(payload); + break; + case PacketType.Pong: + packetOrPbObj = packetTypes.PongPacket.deserialize(payload); + break; + case PacketType.Order: + packetOrPbObj = packetTypes.OrderPacket.deserialize(payload); + break; + case PacketType.OrderInvalidation: + packetOrPbObj = packetTypes.OrderInvalidationPacket.deserialize(payload); + break; + case PacketType.GetOrders: + packetOrPbObj = packetTypes.GetOrdersPacket.deserialize(payload); + break; + case PacketType.Orders: + packetOrPbObj = packetTypes.OrdersPacket.deserialize(payload); + break; + case PacketType.GetNodes: + packetOrPbObj = packetTypes.GetNodesPacket.deserialize(payload); + break; + case PacketType.Nodes: + packetOrPbObj = packetTypes.NodesPacket.deserialize(payload); + break; + case PacketType.SwapRequest: + packetOrPbObj = packetTypes.SwapRequestPacket.deserialize(payload); + break; + case PacketType.SwapAccepted: + packetOrPbObj = packetTypes.SwapAcceptedPacket.deserialize(payload); + break; + case PacketType.SwapComplete: + packetOrPbObj = packetTypes.SwapCompletePacket.deserialize(payload); + break; + case PacketType.SwapFailed: + packetOrPbObj = packetTypes.SwapFailedPacket.deserialize(payload); + break; + default: + throw errors.PARSER_UNKNOWN_PACKET_TYPE(header.type.toString()); + } + + if (!isPacket(packetOrPbObj)) { + throw errors.PARSER_INVALID_PACKET(`${PacketType[header.type]} ${JSON.stringify(packetOrPbObj)}`); + } + + const packet = packetOrPbObj; + if (header.checksum && header.checksum !== packet.checksum()) { + throw errors.PARSER_DATA_INTEGRITY_ERR(`${PacketType[header.type]} ${JSON.stringify(packet)}`); + } + + return packet; + } + + private error = (err: any) => { + this.emit('error', err); + this.resetBuffer(); + } } -export { ParserError, ParserErrorType }; export default Parser; diff --git a/lib/p2p/Peer.ts b/lib/p2p/Peer.ts index d477099cc..7d0ba408d 100644 --- a/lib/p2p/Peer.ts +++ b/lib/p2p/Peer.ts @@ -1,17 +1,23 @@ import assert from 'assert'; import net, { Socket } from 'net'; import { EventEmitter } from 'events'; -import { ReputationEvent, DisconnectionReason } from '../types/enums'; -import Parser, { ParserError, ParserErrorType } from './Parser'; +import crypto from 'crypto'; +import secp256k1 from 'secp256k1'; +import stringify from 'json-stable-stringify'; +import semver from 'semver'; +import { ReputationEvent, DisconnectionReason, NetworkMagic } from '../types/enums'; +import Parser from './Parser'; import * as packets from './packets/types'; import Logger from '../Logger'; import { ms } from '../utils/utils'; import { OutgoingOrder } from '../types/orders'; import { Packet, PacketDirection, PacketType } from './packets'; -import { HandshakeState, Address, NodeConnectionInfo, PoolConfig } from '../types/p2p'; -import errors from './errors'; +import { NodeState, Address, NodeConnectionInfo, PoolConfig } from '../types/p2p'; +import errors, { errorCodes } from './errors'; import addressUtils from '../utils/addressUtils'; -import semver from 'semver'; +import NodeKey from '../nodekey/NodeKey'; +import Network from './Network'; +import Framer from './Framer'; const minCompatibleVersion: string = require('../../package.json').minCompatibleVersion; @@ -31,6 +37,7 @@ interface Peer { on(event: 'packet', listener: (packet: Packet) => void): this; on(event: 'error', listener: (err: Error) => void): this; on(event: 'pairDropped', listener: (pair: string) => void): this; + on(event: 'nodeStateUpdate', listener: () => void): this; once(event: 'open', listener: () => void): this; once(event: 'close', listener: () => void): this; once(event: 'reputation', listener: (event: ReputationEvent) => void): this; @@ -41,6 +48,7 @@ interface Peer { emit(event: 'error', err: Error): boolean; emit(event: 'packet', packet: Packet): boolean; emit(event: 'pairDropped', pair: string): boolean; + emit(event: 'nodeStateUpdate'): boolean; } /** Represents a remote XU peer */ @@ -55,7 +63,7 @@ class Peer extends EventEmitter { public discoverTimer?: NodeJS.Timer; private opened = false; private socket?: Socket; - private parser: Parser = new Parser(); + private parser: Parser; private closed = false; /** Timer to retry connection to peer after the previous attempt failed. */ private retryConnectionTimer?: NodeJS.Timer; @@ -64,12 +72,16 @@ class Peer extends EventEmitter { private pingTimer?: NodeJS.Timer; private responseMap: Map = new Map(); private connectTime!: number; + private connectionRetriesRevoked = false; private lastRecv = 0; private lastSend = 0; - private handshakeState?: HandshakeState; - private connectionRetriesRevoked = false; + private nodeState?: NodeState; + private sessionInitPacket?: packets.SessionInitPacket; + private outEncryptionKey?: Buffer; /** A counter for packets sent to be used for assigning unique packet ids. */ private packetCount = 0; + private network = new Network(NetworkMagic.TestNet); // TODO: inject from constructor to support more networks + private framer: Framer; /** Interval to check required responses from peer. */ private static readonly STALL_INTERVAL = 5000; /** Interval for pinging peers. */ @@ -86,20 +98,24 @@ class Peer extends EventEmitter { private static readonly CONNECTION_RETRIES_MAX_PERIOD = 604800000; private get version(): string { - return this.handshakeState ? this.handshakeState.version : ''; + return this.nodeState ? this.nodeState.version : ''; } /** The hex-encoded node public key for this peer, or undefined if it is still not known. */ public get nodePubKey(): string | undefined { - return this.handshakeState ? this.handshakeState.nodePubKey : undefined; + return this.nodeState ? this.nodeState.nodePubKey : undefined; + } + + public get label(): string { + return this.nodePubKey || addressUtils.toString(this.address); } public get addresses(): Address[] | undefined { - return this.handshakeState ? this.handshakeState.addresses : undefined; + return this.nodeState ? this.nodeState.addresses : undefined; } public get pairs(): string[] | undefined { - return this.handshakeState ? this.handshakeState.pairs : undefined; + return this.nodeState ? this.nodeState.pairs : undefined; } public get connected(): boolean { @@ -109,10 +125,10 @@ class Peer extends EventEmitter { public get info(): PeerInfo { return { address: addressUtils.toString(this.address), - nodePubKey: this.handshakeState ? this.handshakeState.nodePubKey : undefined, + nodePubKey: this.nodeState ? this.nodeState.nodePubKey : undefined, inbound: this.inbound, - pairs: this.handshakeState ? this.handshakeState.pairs : undefined, - xudVersion: this.handshakeState ? this.handshakeState.version : undefined, + pairs: this.nodeState ? this.nodeState.pairs : undefined, + xudVersion: this.nodeState ? this.nodeState.version : undefined, secondsConnected: Math.round((Date.now() - this.connectTime) / 1000), lndbtcPubKey: this.getLndPubKey('BTC'), lndltcPubKey: this.getLndPubKey('LTC'), @@ -125,6 +141,8 @@ class Peer extends EventEmitter { constructor(private logger: Logger, public address: Address, private config: PoolConfig) { super(); + this.framer = new Framer(this.network); + this.parser = new Parser(this.framer); this.bindParser(this.parser); } @@ -143,14 +161,14 @@ class Peer extends EventEmitter { } public getLndPubKey(chain: string): string | undefined { - if (!this.handshakeState) { + if (!this.nodeState) { return; } switch (chain) { case 'BTC': - return this.handshakeState.lndbtcPubKey; + return this.nodeState.lndbtcPubKey; case 'LTC': - return this.handshakeState.lndltcPubKey; + return this.nodeState.lndltcPubKey; default: return; } @@ -175,25 +193,26 @@ class Peer extends EventEmitter { * @param nodePubKey the expected nodePubKey of the node we are opening a connection with * @param retryConnecting whether to retry to connect upon failure */ - public open = async (handshakeData: HandshakeState, nodePubKey?: string, retryConnecting = false): Promise => { + public open = async (ownNodeState: NodeState, nodeKey: NodeKey, expectedNodePubKey?: string, retryConnecting = false): Promise => { assert(!this.opened); assert(!this.closed); - assert(this.inbound || nodePubKey); + assert(this.inbound || expectedNodePubKey); assert(!retryConnecting || !this.inbound); this.opened = true; - this.expectedNodePubKey = nodePubKey; + this.expectedNodePubKey = expectedNodePubKey; await this.initConnection(retryConnecting); this.initStall(); - await this.initHello(handshakeData); + + await this.handshake(ownNodeState, nodeKey); if (this.expectedNodePubKey && this.nodePubKey !== this.expectedNodePubKey) { this.close(DisconnectionReason.UnexpectedIdentity); throw errors.UNEXPECTED_NODE_PUB_KEY(this.nodePubKey!, this.expectedNodePubKey, addressUtils.toString(this.address)); } - if (this.nodePubKey === handshakeData.nodePubKey) { + if (this.nodePubKey === ownNodeState.nodePubKey) { this.close(DisconnectionReason.ConnectedToSelf); throw errors.ATTEMPTED_CONNECTION_TO_SELF; } @@ -240,8 +259,7 @@ class Peer extends EventEmitter { if (this.socket) { if (reason !== undefined) { - const peerId = this.nodePubKey || addressUtils.toString(this.address); - this.logger.debug(`closing socket with peer ${peerId}. reason: ${DisconnectionReason[reason]}`); + this.logger.debug(`Peer (${ this.label }): closing socket. reason: ${DisconnectionReason[reason]}`); this.sentDisconnectionReason = reason; this.sendPacket(new packets.DisconnectingPacket({ reason, payload: reasonPayload })); } @@ -277,9 +295,18 @@ class Peer extends EventEmitter { this.connectTimeout = undefined; } + let rejectionMsg; + if (reason) { + rejectionMsg = `Peer closed due to ${DisconnectionReason[reason]}`; + } else if (this.recvDisconnectionReason) { + rejectionMsg = `Peer disconnected from us due to ${DisconnectionReason[this.recvDisconnectionReason]}`; + } else { + rejectionMsg = `Peer was destroyed`; + } + for (const [packetType, entry] of this.responseMap) { this.responseMap.delete(packetType); - entry.reject(new Error('Peer was destroyed')); + entry.reject(new Error(rejectionMsg)); } this.emit('close'); @@ -290,9 +317,10 @@ class Peer extends EventEmitter { } public sendPacket = (packet: Packet): void => { - this.sendRaw(packet.toRaw()); - const recipient = this.nodePubKey !== undefined ? this.nodePubKey : addressUtils.toString(this.address); - this.logger.trace(`Sent ${PacketType[packet.type]} packet to ${recipient}: ${JSON.stringify(packet)}`); + const data = this.framer.frame(packet, this.outEncryptionKey); + this.sendRaw(data); + + this.logger.trace(`Sent ${PacketType[packet.type]} packet to ${this.label}: ${JSON.stringify(packet)}`); this.packetCount += 1; if (packet.direction === PacketDirection.Request) { @@ -422,17 +450,29 @@ class Peer extends EventEmitter { * Waits for a packet to be received from peer. * @returns A promise that is resolved once the packet is received or rejects on timeout. */ - private wait = (packetId: string, timeout?: number) => { + private wait = (packetId: string, timeout?: number, cb?: (packet: Packet) => void): Promise => { const entry = this.getOrAddPendingResponseEntry(packetId); return new Promise((resolve, reject) => { entry.addJob(resolve, reject); + if (cb) { + entry.addCb(cb); + } + if (timeout) { entry.setTimeout(timeout); } }); } + private waitSessionInit = async (): Promise => { + if (!this.sessionInitPacket) { + await this.wait(PacketType.SessionInit.toString(), Peer.RESPONSE_TIMEOUT); + } + + return this.sessionInitPacket!; + } + /** * Potentially timeout peer if it hasn't responded. */ @@ -441,8 +481,10 @@ class Peer extends EventEmitter { for (const [packetId, entry] of this.responseMap) { if (now > entry.timeout) { - this.emitError(`Peer is stalling (${packetId})`); - entry.reject('response timed out'); + const request = PacketType[parseInt(packetId, 10)] || packetId; + const err = errors.RESPONSE_TIMEOUT(request); + this.emitError(err.message); + entry.reject(err.message); this.close(DisconnectionReason.ResponseStalling, packetId); return; } @@ -481,7 +523,7 @@ class Peer extends EventEmitter { private fulfillResponseEntry = (packet: Packet): boolean => { const { reqId } = packet.header; if (!reqId) { - this.logger.debug(`Peer (${this.nodePubKey}) sent a response packet without reqId`); + this.logger.debug(`Peer (${this.label}) sent a response packet without reqId`); // TODO: penalize return false; } @@ -489,7 +531,7 @@ class Peer extends EventEmitter { const entry = this.responseMap.get(reqId); if (!entry) { - this.logger.debug(`Peer (${this.nodePubKey}) sent an unsolicited response packet (${reqId})`); + this.logger.debug(`Peer (${this.label}) sent an unsolicited response packet (${reqId})`); // TODO: penalize return false; } @@ -531,27 +573,22 @@ class Peer extends EventEmitter { private bindParser = (parser: Parser): void => { parser.on('packet', this.handlePacket); - parser.on('error', (err: ParserError) => { + parser.on('error', (err: {message: string, code: string}) => { if (this.closed) { return; } - switch (err.type) { - case ParserErrorType.InvalidPacket: - this.logger.warn(`parser: invalid peer packet: ${err.payload}`); - this.emit('reputation', ReputationEvent.InvalidPacket); - break; - case ParserErrorType.UnknownPacketType: - this.logger.warn(`parser: unknown peer packet type: ${err.payload}`); - this.emit('reputation', ReputationEvent.UnknownPacketType); - break; - case ParserErrorType.DataIntegrityError: - this.logger.warn(`parser: packet data integrity error: ${err.payload}`); - this.emit('reputation', ReputationEvent.PacketDataIntegrityError); - break; - case ParserErrorType.MaxBufferSizeExceeded: - this.logger.warn(`parser: max buffer size exceeded: ${err.payload}`); - this.emit('reputation', ReputationEvent.MaxParserBufferSizeExceeded); + switch (err.code) { + case errorCodes.PARSER_INVALID_PACKET: + case errorCodes.PARSER_UNKNOWN_PACKET_TYPE: + case errorCodes.PARSER_DATA_INTEGRITY_ERR: + case errorCodes.PARSER_MAX_BUFFER_SIZE_EXCEEDED: + case errorCodes.FRAMER_MSG_NOT_ENCRYPTED: + case errorCodes.FRAMER_INVALID_NETWORK_MAGIC_VALUE: + case errorCodes.FRAMER_INVALID_MSG_LENGTH: + this.logger.warn(`Peer (${this.label}): ${err.message}`); + this.emit('reputation', ReputationEvent.WireProtocolErr); + this.close(DisconnectionReason.WireProtocolErr, err.message); break; } }); @@ -561,8 +598,8 @@ class Peer extends EventEmitter { private isPacketSolicited = (packet: Packet): boolean => { let solicited = true; - if (!this.opened && packet.type !== PacketType.Hello) { - // until the connection is opened, we only accept hello packets + if (!this.opened && packet.type !== PacketType.SessionInit && packet.type !== PacketType.SessionAck) { + // until the connection is opened, we only accept SessionInit/SessionAck packets solicited = false; } if (packet.direction === PacketDirection.Response) { @@ -582,8 +619,12 @@ class Peer extends EventEmitter { if (this.isPacketSolicited(packet)) { switch (packet.type) { - case PacketType.Hello: { - this.handleHello(packet); + case PacketType.SessionInit: { + this.handleSessionInit(packet); + break; + } + case PacketType.NodeStateUpdate: { + this.handleNodeStateUpdate(packet); break; } case PacketType.Ping: { @@ -616,62 +657,98 @@ class Peer extends EventEmitter { } /** - * Sends a hello packet and waits for one to be received, if we haven't received a hello packet already. + * Authenticate the identity of the peer through SessionInit packet + * @param {SessionInitPacket} packet + * @param {NodeKey} nodeKey */ - private initHello = async (handshakeData: HandshakeState) => { - const packet = new packets.HelloPacket(handshakeData); - + private authenticate = (packet: packets.SessionInitPacket, nodeKey: NodeKey) => { + const body = packet.body!; + const { sign, ...bodyWithoutSign } = body; + const { nodePubKey } = body.nodeState; // the peer pubkey + const { peerPubKey } = body; // our pubkey + + // verify that msg was intended for us + if (peerPubKey !== nodeKey.nodePubKey) { + this.emit('reputation', ReputationEvent.InvalidAuth); + this.close(DisconnectionReason.AuthFailureInvalidTarget); + throw errors.AUTH_FAILURE_INVALID_TARGET(nodePubKey, peerPubKey); + } + + // verify that the msg was signed by the peer + const msg = stringify(bodyWithoutSign); + const msgHash = crypto.createHash('sha256').update(msg).digest(); + const verified = secp256k1.verify( + msgHash, + Buffer.from(sign, 'hex'), + Buffer.from(nodePubKey, 'hex'), + ); + + if (!verified) { + this.emit('reputation', ReputationEvent.InvalidAuth); + this.close(DisconnectionReason.AuthFailureInvalidSignature); + throw errors.AUTH_FAILURE_INVALID_SIGNATURE(nodePubKey); + } + } + + private initSession = async (ownNodeState: NodeState, nodeKey: NodeKey, expectedNodePubKey: string): Promise => { + const ECDH = crypto.createECDH('secp256k1'); + const ephemeralPubKey = ECDH.generateKeys().toString('hex'); + const packet = this.createSessionInitPacket(ephemeralPubKey, ownNodeState, expectedNodePubKey, nodeKey); this.sendPacket(packet); - - if (!this.handshakeState) { - // we must wait to receive handshake data before opening the connection - await this.wait(PacketType.Hello.toString(), Peer.RESPONSE_TIMEOUT); - } - - return packet; + await this.wait(packet.header.id, Peer.RESPONSE_TIMEOUT, (packet: Packet) => { + // enabling in-encryption synchronously, + // expecting the following peer msg to be encrypted + const sessionAck: packets.SessionAckPacket = packet; + const key = ECDH.computeSecret(sessionAck.body!.ephemeralPubKey, 'hex'); + this.setInEncryption(key); + }); } - private handleHello = (packet: packets.HelloPacket): void => { - const newHandshakeState = packet.body!; - this.logger.verbose(`received hello packet from ${this.nodePubKey || addressUtils.toString(this.address)}: ${JSON.stringify(newHandshakeState)}`); - if (this.nodePubKey && this.nodePubKey !== newHandshakeState.nodePubKey) { - // peers cannot change their nodepubkey while we are connected to them - // TODO: penalize? - this.close(DisconnectionReason.ForbiddenIdentityUpdate, newHandshakeState.nodePubKey); - return; - } + private ackSession = (sessionInit: packets.SessionInitPacket, nodeKey: NodeKey): void => { + this.authenticate(sessionInit, nodeKey); + this.nodeState = sessionInit.body!.nodeState; - const entry = this.responseMap.get(PacketType.Hello.toString()); + const ECDH = crypto.createECDH('secp256k1'); + const ephemeralPubKey = ECDH.generateKeys().toString('hex'); - if (entry) { - this.responseMap.delete(PacketType.Hello.toString()); - entry.resolve(packet); - } + this.sendPacket(new packets.SessionAckPacket({ ephemeralPubKey }, sessionInit.header.id)); - const prevHandshakeState = this.handshakeState!; - this.handshakeState = newHandshakeState; + // enabling out-encryption synchronously, + // so that the following msg will be encrypted + const key = ECDH.computeSecret(sessionInit.body!.ephemeralPubKey, 'hex'); + this.setOutEncryption(key); + } - prevHandshakeState.pairs.forEach((pairId) => { - if (!newHandshakeState.pairs.includes(pairId)) { - // a trading pair was in the old handshake state but not in the updated one - this.emit('pairDropped', pairId); - } - }); + private handshake = async (ownNodeState: NodeState, nodeKey: NodeKey) => { + if (!this.inbound) { + // outbound handshake + assert(this.expectedNodePubKey); + await this.initSession(ownNodeState, nodeKey, this.expectedNodePubKey!); + const sessionInit = await this.waitSessionInit(); + this.ackSession(sessionInit, nodeKey); + } else { + // inbound handshake + const sessionInit = await this.waitSessionInit(); + this.ackSession(sessionInit, nodeKey); + await this.initSession(ownNodeState, nodeKey, sessionInit.body!.nodeState.nodePubKey); + } } private sendPing = (): packets.PingPacket => { const packet = new packets.PingPacket(); - this.sendPacket(packet); - return packet; } private sendGetNodes = (): packets.PingPacket => { const packet = new packets.GetNodesPacket(); - this.sendPacket(packet); + return packet; + } + private sendPong = (pingId: string): packets.PongPacket => { + const packet = new packets.PongPacket(undefined, pingId); + this.sendPacket(packet); return packet; } @@ -679,10 +756,30 @@ class Peer extends EventEmitter { this.sendPong(packet.header.id); } + private createSessionInitPacket = ( + ephemeralPubKey: string, + ownNodeState: NodeState, + expectedNodePubKey: string, + nodeKey: NodeKey, + ): packets.SessionInitPacket => { + let body: any = { + ephemeralPubKey, + peerPubKey: expectedNodePubKey, + nodeState: ownNodeState, + }; + + const msg = stringify(body); + const msgHash = crypto.createHash('sha256').update(msg).digest(); + const { signature } = secp256k1.sign(msgHash, nodeKey.nodePrivKey); + + body = { ...body, sign: signature.toString('hex') }; + + return new packets.SessionInitPacket(body); + } + private handleDisconnecting = (packet: packets.DisconnectingPacket): void => { if (!this.recvDisconnectionReason && packet.body && packet.body.reason !== undefined) { - const peerId = this.nodePubKey || addressUtils.toString(this.address); - this.logger.debug(`received disconnecting packet from ${peerId}:${JSON.stringify(packet.body)}`); + this.logger.debug(`received disconnecting packet from ${this.label}:${JSON.stringify(packet.body)}`); this.recvDisconnectionReason = packet.body.reason; } else { // protocol violation: packet should be sent once only, with body, with `reason` field @@ -690,12 +787,32 @@ class Peer extends EventEmitter { } } - private sendPong = (pingId: string): packets.PongPacket => { - const packet = new packets.PongPacket(undefined, pingId); + private handleSessionInit = (packet: packets.SessionInitPacket): void => { + this.sessionInitPacket = packet; - this.sendPacket(packet); + const entry = this.responseMap.get(PacketType.SessionInit.toString()); + if (entry) { + this.responseMap.delete(PacketType.SessionInit.toString()); + entry.resolve(packet); + } + } - return packet; + private handleNodeStateUpdate = (packet: packets.NodeStateUpdatePacket): void => { + const nodeStateUpdate = packet.body!; + this.logger.verbose(`received node state update packet from ${this.label}: ${JSON.stringify(nodeStateUpdate)}`); + + this.nodeState = { ...this.nodeState, ...nodeStateUpdate as NodeState }; + this.emit('nodeStateUpdate'); + } + + private setOutEncryption = (key: Buffer) => { + this.outEncryptionKey = key; + this.logger.debug(`Peer (${this.label}) session out-encryption enabled`); + } + + private setInEncryption = (key: Buffer) => { + this.parser.setEncryptionKey(key); + this.logger.debug(`Peer (${this.label}) session in-encryption enabled`); } } @@ -704,11 +821,17 @@ class PendingResponseEntry { public timeout = 0; /** An array of tasks to resolve or reject. */ public jobs: Job[] = []; + /** An array of callbacks to be called synchronously when entry resolve. */ + public callbacks: Function[] = []; public addJob = (resolve: Function, reject: Function) => { this.jobs.push(new Job(resolve, reject)); } + public addCb = (cb: Function) => { + this.callbacks.push(cb); + } + public setTimeout = (timeout: number): void => { this.timeout = ms() + timeout; } @@ -718,7 +841,12 @@ class PendingResponseEntry { job.resolve(result); } + for (const cb of this.callbacks) { + cb(result); + } + this.jobs.length = 0; + this.callbacks.length = 0; } public reject = (err: any) => { diff --git a/lib/p2p/Pool.ts b/lib/p2p/Pool.ts index 09d89e5f0..863d262ef 100644 --- a/lib/p2p/Pool.ts +++ b/lib/p2p/Pool.ts @@ -9,12 +9,13 @@ import { Packet, PacketType } from './packets'; import { OutgoingOrder, OrderPortion, IncomingOrder } from '../types/orders'; import { Models } from '../db/DB'; import Logger from '../Logger'; -import { HandshakeState, Address, NodeConnectionInfo, HandshakeStateUpdate, PoolConfig } from '../types/p2p'; +import { NodeState, Address, NodeConnectionInfo, NodeStateUpdate, PoolConfig } from '../types/p2p'; import addressUtils from '../utils/addressUtils'; import { getExternalIp, ms } from '../utils/utils'; import assert from 'assert'; import { ReputationEvent, DisconnectionReason } from '../types/enums'; import { db } from '../types'; +import NodeKey from '../nodekey/NodeKey'; type NodeReputationInfo = { reputationScore: ReputationEvent; @@ -52,7 +53,9 @@ interface NodeConnectionIterator { /** A class representing a pool of peers that handles network activity. */ class Pool extends EventEmitter { /** The local handshake data to be sent to newly connected peers. */ - public handshakeData!: HandshakeState; + public nodeState!: NodeState; + /** The local node key. */ + private nodeKey!: NodeKey; /** A map of pub keys to nodes for which we have pending outgoing connections. */ private pendingOutboundPeers = new Map(); /** A set of peers for which we have pending incoming connections. */ @@ -94,7 +97,7 @@ class Pool extends EventEmitter { /** * Initialize the Pool by connecting to known nodes and listening to incoming peer connections, if configured to do so. */ - public init = async (handshakeData: HandshakeState): Promise => { + public init = async (ownNodeState: NodeState, nodeKey: NodeKey): Promise => { if (this.connected) { return; } @@ -108,8 +111,9 @@ class Pool extends EventEmitter { } } - this.handshakeData = handshakeData; - this.handshakeData.addresses = this.addresses; + this.nodeState = ownNodeState; + this.nodeState.addresses = this.addresses; + this.nodeKey = nodeKey; this.bindNodeList(); @@ -145,12 +149,12 @@ class Pool extends EventEmitter { } /** - * Updates the handshake data and sends a new Hello packet to currently connected + * Updates the node state and sends node state update packet to currently connected * peers to notify them of the change. */ - public updateHandshake = (handshakeUpdate: HandshakeStateUpdate) => { - this.handshakeData = { ...this.handshakeData, ...handshakeUpdate }; - const packet = new packets.HelloPacket(this.handshakeData); + public updateNodeState = (nodeStateUpdate: NodeStateUpdate) => { + this.nodeState = { ...this.nodeState, ...nodeStateUpdate }; + const packet = new packets.NodeStateUpdatePacket(this.nodeState); this.peers.forEach((peer) => { peer.sendPacket(packet); }); @@ -185,12 +189,12 @@ class Pool extends EventEmitter { } private verifyReachability = () => { - this.handshakeData.addresses!.forEach(async (address) => { + this.nodeState.addresses!.forEach(async (address) => { const externalAddress = addressUtils.toString(address); this.logger.debug(`Verifying reachability of advertised address: ${externalAddress}`); try { const peer = new Peer(Logger.DISABLED_LOGGER, address, this.config); - await peer.open(this.handshakeData, this.handshakeData.nodePubKey); + await peer.open(this.nodeState, this.nodeKey, this.nodeState.nodePubKey); assert(false, errors.ATTEMPTED_CONNECTION_TO_SELF.message); } catch (err) { if (err.code === errors.ATTEMPTED_CONNECTION_TO_SELF.code) { @@ -215,7 +219,7 @@ class Pool extends EventEmitter { const connectionPromises: Promise[] = []; nodes.forEach((node) => { // check that this node is not ourselves - const isNotUs = node.nodePubKey !== this.handshakeData.nodePubKey; + const isNotUs = node.nodePubKey !== this.nodeState.nodePubKey; // check that it has listening addresses, const hasAddresses = node.lastAddress || node.addresses.length; @@ -300,7 +304,7 @@ class Pool extends EventEmitter { * @returns the connected peer */ public addOutbound = async (address: Address, nodePubKey: string, retryConnecting: boolean, revokeConnectionRetries: boolean): Promise => { - if (nodePubKey === this.handshakeData.nodePubKey) { + if (nodePubKey === this.nodeState.nodePubKey) { const err = errors.ATTEMPTED_CONNECTION_TO_SELF; this.logger.warn(err.message); throw err; @@ -350,11 +354,10 @@ class Pool extends EventEmitter { if (!isBanned) { this.bindPeer(peer); try { - await peer.open(this.handshakeData, nodePubKey, retryConnecting); + await peer.open(this.nodeState, this.nodeKey, nodePubKey, retryConnecting); } catch (err) { // we don't have `nodePubKey` for inbound connections, which might fail on handshake - const id = nodePubKey || addressUtils.toString(peer.address); - this.logger.warn(`could not open connection to peer (${id}): ${err.message}`); + this.logger.warn(`could not open connection to peer (${peer.label}): ${err.message}`); if (err.code === errorCodes.CONNECTION_RETRIES_MAX_PERIOD_EXCEEDED) { await this.nodes.removeAddress(nodePubKey!, peer.address); @@ -542,7 +545,7 @@ class Pool extends EventEmitter { } private handleOpen = async (peer: Peer): Promise => { - if (!peer.nodePubKey || peer.nodePubKey === this.handshakeData.nodePubKey) { + if (!peer.nodePubKey || peer.nodePubKey === this.nodeState.nodePubKey) { return; } @@ -575,9 +578,9 @@ class Pool extends EventEmitter { this.peers.set(peer.nodePubKey, peer); peer.active = true; - if (this.handshakeData.pairs.length > 0) { - // request peer's orders - peer.sendPacket(new packets.GetOrdersPacket({ pairIds: this.handshakeData.pairs })); + // request peer's orders + if (this.nodeState.pairs.length > 0) { + peer.sendPacket(new packets.GetOrdersPacket({ pairIds: this.nodeState.pairs })); } // if outbound, update the `lastConnected` field for the address we're actually connected to @@ -642,8 +645,8 @@ class Pool extends EventEmitter { peer.on('error', (err) => { // The only situation in which the node should be connected to itself is the // reachability check of the advertised addresses and we don't have to log that - if (peer.nodePubKey !== this.handshakeData.nodePubKey) { - this.logger.error(`peer error (${peer.nodePubKey}): ${err.message}`); + if (peer.nodePubKey !== this.nodeState.nodePubKey) { + this.logger.error(`Peer (${peer.label}): error: ${err.message}`); } }); @@ -655,7 +658,7 @@ class Pool extends EventEmitter { peer.once('close', () => this.handlePeerClose(peer)); peer.once('reputation', async (event) => { - this.logger.debug(`Peer (${peer.nodePubKey || addressUtils.toString(peer.address)}), received reputation event: ${ReputationEvent[event]}`); + this.logger.debug(`Peer (${peer.label}): reputation event: ${ReputationEvent[event]}`); if (peer.nodePubKey) { await this.nodes.addReputationEvent(peer.nodePubKey, event); } diff --git a/lib/p2p/errors.ts b/lib/p2p/errors.ts index ab37e6dab..f80e9f441 100644 --- a/lib/p2p/errors.ts +++ b/lib/p2p/errors.ts @@ -11,12 +11,22 @@ const errorCodes = { EXTERNAL_IP_UNRETRIEVABLE: codesPrefix.concat('.5'), CONNECTION_RETRIES_MAX_PERIOD_EXCEEDED: codesPrefix.concat('.6'), CONNECTION_RETRIES_REVOKED: codesPrefix.concat('.7'), - COULD_NOT_CONNECT: codesPrefix.concat('.8'), - NODE_UNKNOWN: codesPrefix.concat('.9'), - NODE_ALREADY_BANNED: codesPrefix.concat('.10'), - NODE_NOT_BANNED: codesPrefix.concat('.11'), - NODE_IS_BANNED: codesPrefix.concat('.12'), - ALREADY_CONNECTING: codesPrefix.concat('.13'), + COULD_NOT_CONNECT: codesPrefix.concat('.7'), + NODE_UNKNOWN: codesPrefix.concat('.8'), + NODE_ALREADY_BANNED: codesPrefix.concat('.9'), + NODE_NOT_BANNED: codesPrefix.concat('.10'), + NODE_IS_BANNED: codesPrefix.concat('.11'), + ALREADY_CONNECTING: codesPrefix.concat('.12'), + RESPONSE_TIMEOUT: codesPrefix.concat('.13'), + AUTH_FAILURE_INVALID_TARGET: codesPrefix.concat('.14'), + AUTH_FAILURE_INVALID_SIGNATURE: codesPrefix.concat('.15'), + PARSER_INVALID_PACKET: codesPrefix.concat('.16'), + PARSER_UNKNOWN_PACKET_TYPE: codesPrefix.concat('.17'), + PARSER_DATA_INTEGRITY_ERR: codesPrefix.concat('.18'), + PARSER_MAX_BUFFER_SIZE_EXCEEDED: codesPrefix.concat('.19'), + FRAMER_MSG_NOT_ENCRYPTED: codesPrefix.concat('.`20'), + FRAMER_INVALID_NETWORK_MAGIC_VALUE: codesPrefix.concat('.21'), + FRAMER_INVALID_MSG_LENGTH: codesPrefix.concat('.22'), }; const errors = { @@ -54,7 +64,7 @@ const errors = { }, CONNECTION_RETRIES_REVOKED: { message: `Connection retry attempts to peer were revoked`, - code: errorCodes.CONNECTION_RETRIES_MAX_PERIOD_EXCEEDED, + code: errorCodes.CONNECTION_RETRIES_REVOKED, }, COULD_NOT_CONNECT: (address: Address, err: Error) => ({ message: `could not connect to peer at ${addressUtils.toString(address)}: ${err.message}`, @@ -80,6 +90,46 @@ const errors = { message: `there is already an existing connection attempt to node ${nodePubKey}`, code: errorCodes.ALREADY_CONNECTING, }), + RESPONSE_TIMEOUT: (request: string) => ({ + message: `response timeout (${request}) `, + code: errorCodes.RESPONSE_TIMEOUT, + }), + AUTH_FAILURE_INVALID_TARGET: (nodePubKey: string, target: string) => ({ + message: `could not authenticate peer (${nodePubKey}): invalid target (${target})`, + code: errorCodes.AUTH_FAILURE_INVALID_TARGET, + }), + AUTH_FAILURE_INVALID_SIGNATURE: (nodePubKey: string) => ({ + message: `could not authenticate peer (${nodePubKey}): invalid signature`, + code: errorCodes.AUTH_FAILURE_INVALID_SIGNATURE, + }), + PARSER_INVALID_PACKET: (packet: string) => ({ + message: `parser: invalid packet: ${packet}`, + code: errorCodes.PARSER_INVALID_PACKET, + }), + PARSER_UNKNOWN_PACKET_TYPE: (packetType: string) => ({ + message: `parser: unknown packet type: ${packetType}`, + code: errorCodes.PARSER_UNKNOWN_PACKET_TYPE, + }), + PARSER_DATA_INTEGRITY_ERR: (packet: string) => ({ + message: `parser: packet data integrity error: ${packet}`, + code: errorCodes.PARSER_DATA_INTEGRITY_ERR, + }), + PARSER_MAX_BUFFER_SIZE_EXCEEDED: (size: number) => ({ + message: `parser: max buffer size exceeded: ${size.toString()}`, + code: errorCodes.PARSER_MAX_BUFFER_SIZE_EXCEEDED, + }), + FRAMER_MSG_NOT_ENCRYPTED: { + message: `framer: msg is not encrypted`, + code: errorCodes.FRAMER_MSG_NOT_ENCRYPTED, + }, + FRAMER_INVALID_NETWORK_MAGIC_VALUE: { + message: `framer: msg has an invalid network magic value (might be encrypted)`, + code: errorCodes.FRAMER_INVALID_NETWORK_MAGIC_VALUE, + }, + FRAMER_INVALID_MSG_LENGTH: (expected: number, found: number) => ({ + message: `framer: invalid msg length (expected: ${expected} found: ${found})`, + code: errorCodes.FRAMER_INVALID_NETWORK_MAGIC_VALUE, + }), }; export { errorCodes }; diff --git a/lib/p2p/packets/Packet.ts b/lib/p2p/packets/Packet.ts index 14291ef91..d3075643f 100644 --- a/lib/p2p/packets/Packet.ts +++ b/lib/p2p/packets/Packet.ts @@ -1,6 +1,5 @@ import PacketType from './PacketType'; -import CryptoJS from 'crypto-js'; -import MD5 from 'crypto-js/md5'; +import crypto from 'crypto'; import uuidv1 from 'uuid/v1'; import stringify from 'json-stable-stringify'; @@ -9,9 +8,6 @@ type PacketHeader = { id: string; /** The id of the received packet to which this packet is responding. */ reqId?: string; - type?: PacketType; - /** The Base64 encoded MD5 hash of the body of the packet, to be used for error checking. */ - hash?: string; }; interface PacketInterface { @@ -82,46 +78,33 @@ abstract class Packet implements PacketInterface { if (bodyOrPacket) { this.body = bodyOrPacket; - this.header.hash = Packet.hash(bodyOrPacket); } } } - private static hash(value: any): string { - return MD5(stringify(value)).toString(CryptoJS.enc.Base64); - } - public abstract serialize(): Uint8Array; - /** - * Verify the header hash against the packet body. - */ - public verifyDataIntegrity(): boolean { - if (!this.body) { - return true; - } - - if (!this.header.hash) { - return false; - } - - return this.header.hash === Packet.hash(this.body); + public toJSON = () => { + return stringify({ header: this.header, body: this.body }); } /** * Serialize this packet to binary Buffer. * @returns Buffer representation of the packet */ - public toRaw(): Buffer { - const msg = this.serialize(); - - const type = Buffer.alloc(1); - type.writeUInt8(this.type, 0, true); - - const size = Buffer.allocUnsafe(4); - size.writeUInt32LE(msg.length, 0, true); + public toRaw = (): Buffer => { + return Buffer.from(this.serialize().buffer as ArrayBuffer); + } - return Buffer.concat([type, size, Buffer.from(msg.buffer as ArrayBuffer)]); + /** + * Calculating the packet checksum using its JSON representation hash first 4 bytes. + */ + public checksum = (): number => { + return crypto + .createHash('sha256') + .update(this.toJSON()) + .digest() + .readUInt32LE(0, true); } } diff --git a/lib/p2p/packets/PacketType.ts b/lib/p2p/packets/PacketType.ts index c93cf343a..0b6734c14 100644 --- a/lib/p2p/packets/PacketType.ts +++ b/lib/p2p/packets/PacketType.ts @@ -1,18 +1,20 @@ enum PacketType { - Hello = 0, - Disconnecting = 1, - Ping = 2, - Pong = 3, - Order = 4, - OrderInvalidation = 5, - GetOrders = 6, - Orders = 7, - GetNodes = 8, - Nodes = 9, - SwapRequest = 10, - SwapAccepted = 11, - SwapComplete = 12, - SwapFailed = 13, + SessionInit = 0, + SessionAck = 1, + NodeStateUpdate = 2, + Disconnecting = 3, + Ping = 4, + Pong = 5, + Order = 6, + OrderInvalidation = 7, + GetOrders = 8, + Orders = 9, + GetNodes = 10, + Nodes = 11, + SwapRequest = 12, + SwapAccepted = 13, + SwapComplete = 14, + SwapFailed = 15, } export default PacketType; diff --git a/lib/p2p/packets/types/DisconnectingPacket.ts b/lib/p2p/packets/types/DisconnectingPacket.ts index fc3e74157..e1d78e551 100644 --- a/lib/p2p/packets/types/DisconnectingPacket.ts +++ b/lib/p2p/packets/types/DisconnectingPacket.ts @@ -25,7 +25,6 @@ class DisconnectingPacket extends Packet { private static validate = (msg: pb.DisconnectingPacket.AsObject): boolean => { return !!(msg.id - && msg.hash && msg.reason ); } @@ -34,7 +33,6 @@ class DisconnectingPacket extends Packet { return new DisconnectingPacket({ header: { id: obj.id, - hash: obj.hash, }, body: removeUndefinedProps({ reason: obj.reason, @@ -43,10 +41,9 @@ class DisconnectingPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.DisconnectingPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setReason(this.body!.reason); msg.setPayload(this.body!.payload!); diff --git a/lib/p2p/packets/types/GetNodesPacket.ts b/lib/p2p/packets/types/GetNodesPacket.ts index d6bcb44f8..138c85acd 100644 --- a/lib/p2p/packets/types/GetNodesPacket.ts +++ b/lib/p2p/packets/types/GetNodesPacket.ts @@ -1,8 +1,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; -import DisconnectingPacket from './DisconnectingPacket'; class GetNodesPacket extends Packet { public get type() { @@ -30,7 +28,7 @@ class GetNodesPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.PingPacket(); msg.setId(this.header.id); diff --git a/lib/p2p/packets/types/GetOrdersPacket.ts b/lib/p2p/packets/types/GetOrdersPacket.ts index 5a510373b..6137dbafe 100644 --- a/lib/p2p/packets/types/GetOrdersPacket.ts +++ b/lib/p2p/packets/types/GetOrdersPacket.ts @@ -1,8 +1,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; -import HelloPacket from './HelloPacket'; export type GetOrdersPacketBody = { pairIds: string[], @@ -24,7 +22,6 @@ class GetOrdersPacket extends Packet { private static validate = (obj: pb.GetOrdersPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.pairIdsList.length > 0 ); } @@ -33,7 +30,6 @@ class GetOrdersPacket extends Packet { return new GetOrdersPacket({ header: { id: obj.id, - hash: obj.hash, }, body: { pairIds: obj.pairIdsList, @@ -41,10 +37,9 @@ class GetOrdersPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.GetOrdersPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setPairIdsList(this.body!.pairIds); return msg.serializeBinary(); diff --git a/lib/p2p/packets/types/HelloPacket.ts b/lib/p2p/packets/types/HelloPacket.ts deleted file mode 100644 index 13fbd0b26..000000000 --- a/lib/p2p/packets/types/HelloPacket.ts +++ /dev/null @@ -1,70 +0,0 @@ -import Packet, { PacketDirection } from '../Packet'; -import PacketType from '../PacketType'; -import { HandshakeState } from '../../../types/p2p'; -import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; - -class HelloPacket extends Packet { - public get type() { - return PacketType.Hello; - } - - public get direction() { - return PacketDirection.Unilateral; - } - - public static deserialize = (binary: Uint8Array): HelloPacket | pb.HelloPacket.AsObject => { - const obj = pb.HelloPacket.deserializeBinary(binary).toObject(); - return HelloPacket.validate(obj) ? HelloPacket.convert(obj) : obj; - } - - private static validate = (obj: pb.HelloPacket.AsObject): boolean => { - return !!(obj.id - && obj.hash - && obj.version - && obj.nodePubKey - && obj.pairsList - && obj.addressesList.every(addr => !!addr.host) - ); - } - - private static convert = (obj: pb.HelloPacket.AsObject): HelloPacket => { - return new HelloPacket({ - header: { - id: obj.id, - hash: obj.hash, - }, - body: removeUndefinedProps({ - version: obj.version, - nodePubKey: obj.nodePubKey, - pairs: obj.pairsList, - addresses: obj.addressesList, - raidenAddress: obj.raidenAddress || undefined, - lndbtcPubKey: obj.lndbtcPubKey || undefined, - lndltcPubKey: obj.lndltcPubKey || undefined, - }), - }); - } - - public serialize(): Uint8Array { - const msg = new pb.HelloPacket(); - msg.setId(this.header.id); - msg.setHash(this.header.hash!); - msg.setVersion(this.body!.version); - msg.setNodePubKey(this.body!.nodePubKey); - msg.setPairsList(this.body!.pairs); - msg.setAddressesList(this.body!.addresses!.map((addr) => { - const pbAddr = new pb.Address(); - pbAddr.setHost(addr.host); - pbAddr.setPort(addr.port); - return pbAddr; - })); - msg.setRaidenAddress(this.body!.raidenAddress!); - msg.setLndbtcPubKey(this.body!.lndbtcPubKey!); - msg.setLndltcPubKey(this.body!.lndltcPubKey!); - - return msg.serializeBinary(); - } -} - -export default HelloPacket; diff --git a/lib/p2p/packets/types/NodeStateUpdatePacket.ts b/lib/p2p/packets/types/NodeStateUpdatePacket.ts new file mode 100644 index 000000000..f9e8054f3 --- /dev/null +++ b/lib/p2p/packets/types/NodeStateUpdatePacket.ts @@ -0,0 +1,62 @@ +import Packet, { PacketDirection } from '../Packet'; +import PacketType from '../PacketType'; +import { NodeStateUpdate } from '../../../types/p2p'; +import * as pb from '../../../proto/xudp2p_pb'; +import { removeUndefinedProps } from '../../../utils/utils'; + +class NodeStateUpdatePacket extends Packet { + public get type() { + return PacketType.NodeStateUpdate; + } + + public get direction() { + return PacketDirection.Unilateral; + } + + public static deserialize = (binary: Uint8Array): NodeStateUpdatePacket | pb.NodeStateUpdatePacket.AsObject => { + const obj = pb.NodeStateUpdatePacket.deserializeBinary(binary).toObject(); + return NodeStateUpdatePacket.validate(obj) ? NodeStateUpdatePacket.convert(obj) : obj; + } + + private static validate = (obj: pb.NodeStateUpdatePacket.AsObject): boolean => { + return !!(obj.id + && obj.pairsList + && obj.addressesList.filter(addr => addr.host).length === obj.addressesList.length + ); + } + + private static convert = (obj: pb.NodeStateUpdatePacket.AsObject): NodeStateUpdatePacket => { + return new NodeStateUpdatePacket({ + header: { + id: obj.id, + }, + body: removeUndefinedProps({ + pairs: obj.pairsList, + addresses: obj.addressesList, + raidenAddress: obj.raidenAddress || undefined, + lndbtcPubKey: obj.lndBtcPubKey || undefined, + lndltcPubKey: obj.lndLtcPubKey || undefined, + }), + }); + } + + public serialize = (): Uint8Array => { + const msg = new pb.NodeStateUpdatePacket(); + + msg.setId(this.header.id); + msg.setPairsList(this.body!.pairs!); + msg.setAddressesList(this.body!.addresses!.map((addr) => { + const pbAddr = new pb.Address(); + pbAddr.setHost(addr.host); + pbAddr.setPort(addr.port); + return pbAddr; + })); + msg.setRaidenAddress(this.body!.raidenAddress!); + msg.setLndBtcPubKey(this.body!.lndbtcPubKey!); + msg.setLndLtcPubKey(this.body!.lndltcPubKey!); + + return msg.serializeBinary(); + } +} + +export default NodeStateUpdatePacket; diff --git a/lib/p2p/packets/types/NodesPacket.ts b/lib/p2p/packets/types/NodesPacket.ts index 3f31b7775..e3b29554f 100644 --- a/lib/p2p/packets/types/NodesPacket.ts +++ b/lib/p2p/packets/types/NodesPacket.ts @@ -2,8 +2,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import { NodeConnectionInfo } from '../../../types/p2p'; import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; -import HelloPacket from './HelloPacket'; class NodesPacket extends Packet { public get type() { @@ -21,7 +19,6 @@ class NodesPacket extends Packet { private static validate = (obj: pb.NodesPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.reqId && obj.nodesList.filter(node => node.nodePubKey @@ -37,7 +34,6 @@ class NodesPacket extends Packet { return new NodesPacket({ header: { id: obj.id, - hash: obj.hash, reqId: obj.reqId, }, body: obj.nodesList.map(node => ({ @@ -47,10 +43,9 @@ class NodesPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.NodesPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setReqId(this.header.reqId!); msg.setNodesList(this.body!.map((node) => { const pbNode = new pb.Node(); diff --git a/lib/p2p/packets/types/OrderInvalidationPacket.ts b/lib/p2p/packets/types/OrderInvalidationPacket.ts index 5e23e77c9..2ab4a3ac9 100644 --- a/lib/p2p/packets/types/OrderInvalidationPacket.ts +++ b/lib/p2p/packets/types/OrderInvalidationPacket.ts @@ -2,7 +2,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import { OrderPortion } from '../../../types/orders'; import * as pb from '../../../proto/xudp2p_pb'; -import OrderPacket from './OrderPacket'; type OrderInvalidationPacketBody = OrderPortion; @@ -22,7 +21,6 @@ class OrderInvalidationPacket extends Packet { private static validate = (obj: pb.OrderInvalidationPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.orderId && obj.pairId && obj.quantity @@ -33,7 +31,6 @@ class OrderInvalidationPacket extends Packet { return new OrderInvalidationPacket({ header: { id: obj.id, - hash: obj.hash, }, body: { id: obj.orderId, @@ -43,10 +40,9 @@ class OrderInvalidationPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.OrderInvalidationPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setOrderId(this.body!.id); msg.setPairId(this.body!.pairId); msg.setQuantity(this.body!.quantity); diff --git a/lib/p2p/packets/types/OrderPacket.ts b/lib/p2p/packets/types/OrderPacket.ts index c3be6a943..388fc3fc8 100644 --- a/lib/p2p/packets/types/OrderPacket.ts +++ b/lib/p2p/packets/types/OrderPacket.ts @@ -2,8 +2,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import { OutgoingOrder } from '../../../types/orders'; import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; -import HelloPacket from './HelloPacket'; class OrderPacket extends Packet { public get type() { @@ -21,7 +19,6 @@ class OrderPacket extends Packet { private static validate = (obj: pb.OrderPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.id && obj.order && obj.order.pairId @@ -34,7 +31,6 @@ class OrderPacket extends Packet { return new OrderPacket({ header: { id: obj.id, - hash: obj.hash, }, body: { id: obj.order!.id, @@ -46,7 +42,7 @@ class OrderPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const pbOrder = new pb.Order(); pbOrder.setId(this.body!.id); pbOrder.setPairId(this.body!.pairId); @@ -56,7 +52,6 @@ class OrderPacket extends Packet { const msg = new pb.OrderPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setOrder(pbOrder); return msg.serializeBinary(); diff --git a/lib/p2p/packets/types/OrdersPacket.ts b/lib/p2p/packets/types/OrdersPacket.ts index 4f5c12f21..0bf6d5ec9 100644 --- a/lib/p2p/packets/types/OrdersPacket.ts +++ b/lib/p2p/packets/types/OrdersPacket.ts @@ -21,7 +21,6 @@ class OrdersPacket extends Packet { private static validate = (obj: pb.OrdersPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.reqId && obj.ordersList.every(order => !!order.id @@ -36,7 +35,6 @@ class OrdersPacket extends Packet { return new OrdersPacket({ header: { id: obj.id, - hash: obj.hash, reqId: obj.reqId, }, body: obj.ordersList.map(pbOrder => ({ @@ -49,10 +47,9 @@ class OrdersPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.OrdersPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setReqId(this.header.reqId!); msg.setOrdersList(this.body!.map((order) => { const pbOrder = new pb.Order(); diff --git a/lib/p2p/packets/types/PingPacket.ts b/lib/p2p/packets/types/PingPacket.ts index 90e246b85..651f64b58 100644 --- a/lib/p2p/packets/types/PingPacket.ts +++ b/lib/p2p/packets/types/PingPacket.ts @@ -1,8 +1,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; -import HelloPacket from './HelloPacket'; class PingPacket extends Packet { public get type() { @@ -30,7 +28,7 @@ class PingPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.PingPacket(); msg.setId(this.header.id); diff --git a/lib/p2p/packets/types/PongPacket.ts b/lib/p2p/packets/types/PongPacket.ts index 6b7226637..6bd7cf091 100644 --- a/lib/p2p/packets/types/PongPacket.ts +++ b/lib/p2p/packets/types/PongPacket.ts @@ -1,8 +1,6 @@ import Packet, { PacketDirection } from '../Packet'; import PacketType from '../PacketType'; import * as pb from '../../../proto/xudp2p_pb'; -import { removeUndefinedProps } from '../../../utils/utils'; -import HelloPacket from './HelloPacket'; import PingPacket from './PingPacket'; class PongPacket extends Packet { @@ -34,7 +32,7 @@ class PongPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.PongPacket(); msg.setId(this.header.id); msg.setReqId(this.header.reqId!); diff --git a/lib/p2p/packets/types/SessionAckPacket.ts b/lib/p2p/packets/types/SessionAckPacket.ts new file mode 100644 index 000000000..ece976b73 --- /dev/null +++ b/lib/p2p/packets/types/SessionAckPacket.ts @@ -0,0 +1,54 @@ +import Packet, { PacketDirection } from '../Packet'; +import PacketType from '../PacketType'; +import { NodeState } from '../../../types/p2p'; +import * as pb from '../../../proto/xudp2p_pb'; +import { removeUndefinedProps } from '../../../utils/utils'; + +export type SessionAckPacketBody = { + ephemeralPubKey: string; +}; + +class SessionAckPacket extends Packet { + public get type() { + return PacketType.SessionAck; + } + + public get direction() { + return PacketDirection.Response; + } + + public static deserialize = (binary: Uint8Array): SessionAckPacket | pb.SessionAckPacket.AsObject => { + const obj = pb.SessionAckPacket.deserializeBinary(binary).toObject(); + return SessionAckPacket.validate(obj) ? SessionAckPacket.convert(obj) : obj; + } + + private static validate = (obj: pb.SessionAckPacket.AsObject): boolean => { + return !!(obj.id + && obj.reqId + && obj.ephemeralPubKey + ); + } + + private static convert = (obj: pb.SessionAckPacket.AsObject): SessionAckPacket => { + return new SessionAckPacket({ + header: { + id: obj.id, + reqId: obj.reqId, + }, + body: { + ephemeralPubKey: obj.ephemeralPubKey, + }, + }); + } + + public serialize = (): Uint8Array => { + const msg = new pb.SessionAckPacket(); + msg.setId(this.header.id); + msg.setReqId(this.header.reqId!); + msg.setEphemeralPubKey(this.body!.ephemeralPubKey); + + return msg.serializeBinary(); + } +} + +export default SessionAckPacket; diff --git a/lib/p2p/packets/types/SessionInitPacket.ts b/lib/p2p/packets/types/SessionInitPacket.ts new file mode 100644 index 000000000..e4a84e090 --- /dev/null +++ b/lib/p2p/packets/types/SessionInitPacket.ts @@ -0,0 +1,90 @@ +import Packet, { PacketDirection } from '../Packet'; +import PacketType from '../PacketType'; +import { NodeState } from '../../../types/p2p'; +import * as pb from '../../../proto/xudp2p_pb'; +import { removeUndefinedProps } from '../../../utils/utils'; + +export type SessionInitPacketBody = { + sign: string; + ephemeralPubKey: string; + peerPubKey: string; + nodeState: NodeState; +}; + +class SessionInitPacket extends Packet { + public get type() { + return PacketType.SessionInit; + } + + public get direction() { + return PacketDirection.Request; + } + + public static deserialize = (binary: Uint8Array): SessionInitPacket | pb.SessionInitPacket.AsObject => { + const obj = pb.SessionInitPacket.deserializeBinary(binary).toObject(); + return SessionInitPacket.validate(obj) ? SessionInitPacket.convert(obj) : obj; + } + + private static validate = (obj: pb.SessionInitPacket.AsObject): boolean => { + return !!(obj.id + && obj.sign + && obj.ephemeralPubKey + && obj.peerPubKey + && obj.nodeState + && obj.nodeState.version + && obj.nodeState.nodePubKey + && obj.nodeState.pairsList + && obj.nodeState.addressesList.filter(addr => addr.host).length === obj.nodeState.addressesList.length + ); + } + + private static convert = (obj: pb.SessionInitPacket.AsObject): SessionInitPacket => { + return new SessionInitPacket({ + header: { + id: obj.id, + }, + body: { + sign: obj.sign, + peerPubKey: obj.peerPubKey, + ephemeralPubKey: obj.ephemeralPubKey, + nodeState: removeUndefinedProps({ + version: obj.nodeState!.version, + nodePubKey: obj.nodeState!.nodePubKey, + pairs: obj.nodeState!.pairsList, + addresses: obj.nodeState!.addressesList, + raidenAddress: obj.nodeState!.raidenAddress || undefined, + lndbtcPubKey: obj.nodeState!.lndBtcPubKey || undefined, + lndltcPubKey: obj.nodeState!.lndLtcPubKey || undefined, + }), + }, + }); + } + + public serialize = (): Uint8Array => { + const msg = new pb.SessionInitPacket(); + msg.setId(this.header.id); + msg.setSign(this.body!.sign); + msg.setPeerPubKey(this.body!.peerPubKey); + msg.setEphemeralPubKey(this.body!.ephemeralPubKey); + msg.setNodeState((() => { + const pbNodeState = new pb.NodeState(); + pbNodeState.setVersion(this.body!.nodeState.version); + pbNodeState.setNodePubKey(this.body!.nodeState.nodePubKey); + pbNodeState.setPairsList(this.body!.nodeState.pairs); + pbNodeState.setAddressesList(this.body!.nodeState.addresses!.map((addr) => { + const pbAddr = new pb.Address(); + pbAddr.setHost(addr.host); + pbAddr.setPort(addr.port); + return pbAddr; + })); + pbNodeState.setRaidenAddress(this.body!.nodeState.raidenAddress!); + pbNodeState.setLndBtcPubKey(this.body!.nodeState.lndbtcPubKey!); + pbNodeState.setLndLtcPubKey(this.body!.nodeState.lndltcPubKey!); + return pbNodeState; + })()); + + return msg.serializeBinary(); + } +} + +export default SessionInitPacket; diff --git a/lib/p2p/packets/types/SwapAcceptedPacket.ts b/lib/p2p/packets/types/SwapAcceptedPacket.ts index 07e8194bf..5a5dff465 100644 --- a/lib/p2p/packets/types/SwapAcceptedPacket.ts +++ b/lib/p2p/packets/types/SwapAcceptedPacket.ts @@ -26,7 +26,6 @@ class SwapAcceptedPacket extends Packet { private static validate = (obj: pb.SwapAcceptedPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.reqId && obj.rHash && obj.quantity @@ -38,7 +37,6 @@ class SwapAcceptedPacket extends Packet { return new SwapAcceptedPacket({ header: { id: obj.id, - hash: obj.hash, reqId: obj.reqId, }, body: { @@ -49,10 +47,9 @@ class SwapAcceptedPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.SwapAcceptedPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setReqId(this.header.reqId!); msg.setRHash(this.body!.rHash); msg.setQuantity(this.body!.quantity); diff --git a/lib/p2p/packets/types/SwapCompletePacket.ts b/lib/p2p/packets/types/SwapCompletePacket.ts index 3a94289b0..3d27b3656 100644 --- a/lib/p2p/packets/types/SwapCompletePacket.ts +++ b/lib/p2p/packets/types/SwapCompletePacket.ts @@ -22,7 +22,6 @@ class SwapCompletePacket extends Packet { private static validate = (obj: pb.SwapCompletePacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.rHash ); } @@ -31,7 +30,6 @@ class SwapCompletePacket extends Packet { return new SwapCompletePacket({ header: { id: obj.id, - hash: obj.hash, }, body: { rHash: obj.rHash, @@ -39,10 +37,9 @@ class SwapCompletePacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.SwapCompletePacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setRHash(this.body!.rHash); return msg.serializeBinary(); diff --git a/lib/p2p/packets/types/SwapFailedPacket.ts b/lib/p2p/packets/types/SwapFailedPacket.ts index 8e78ffc0e..c0501853b 100644 --- a/lib/p2p/packets/types/SwapFailedPacket.ts +++ b/lib/p2p/packets/types/SwapFailedPacket.ts @@ -31,7 +31,6 @@ class SwapFailedPacket extends Packet { private static validate = (obj: pb.SwapFailedPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.rHash ); } @@ -40,7 +39,6 @@ class SwapFailedPacket extends Packet { return new SwapFailedPacket({ header: removeUndefinedProps({ id: obj.id, - hash: obj.hash, reqId: obj.reqId || undefined, }), body: removeUndefinedProps({ @@ -51,10 +49,9 @@ class SwapFailedPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.SwapFailedPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setReqId(this.header.reqId!); msg.setRHash(this.body!.rHash); if (this.body!.errorMessage) { diff --git a/lib/p2p/packets/types/SwapRequestPacket.ts b/lib/p2p/packets/types/SwapRequestPacket.ts index 1e6c284ef..5e3334be9 100644 --- a/lib/p2p/packets/types/SwapRequestPacket.ts +++ b/lib/p2p/packets/types/SwapRequestPacket.ts @@ -26,7 +26,6 @@ class SwapRequestPacket extends Packet { private static validate = (obj: pb.SwapRequestPacket.AsObject): boolean => { return !!(obj.id - && obj.hash && obj.proposedQuantity && obj.pairId && obj.orderId @@ -39,7 +38,6 @@ class SwapRequestPacket extends Packet { return new SwapRequestPacket({ header: { id: obj.id, - hash: obj.hash, }, body: { proposedQuantity: obj.proposedQuantity, @@ -51,10 +49,9 @@ class SwapRequestPacket extends Packet { }); } - public serialize(): Uint8Array { + public serialize = (): Uint8Array => { const msg = new pb.SwapRequestPacket(); msg.setId(this.header.id); - msg.setHash(this.header.hash!); msg.setProposedQuantity(this.body!.proposedQuantity); msg.setPairId(this.body!.pairId); msg.setOrderId(this.body!.orderId); diff --git a/lib/p2p/packets/types/index.ts b/lib/p2p/packets/types/index.ts index c38148765..dfa548b24 100644 --- a/lib/p2p/packets/types/index.ts +++ b/lib/p2p/packets/types/index.ts @@ -1,5 +1,7 @@ export { default as OrderPacket } from './OrderPacket'; -export { default as HelloPacket } from './HelloPacket'; +export { default as SessionInitPacket } from './SessionInitPacket'; +export { default as SessionAckPacket } from './SessionAckPacket'; +export { default as NodeStateUpdatePacket } from './NodeStateUpdatePacket'; export { default as DisconnectingPacket } from './DisconnectingPacket'; export { default as PingPacket } from './PingPacket'; export { default as PongPacket } from './PongPacket'; diff --git a/lib/proto/xudp2p_pb.d.ts b/lib/proto/xudp2p_pb.d.ts index 5831af6f3..240ea468d 100644 --- a/lib/proto/xudp2p_pb.d.ts +++ b/lib/proto/xudp2p_pb.d.ts @@ -89,6 +89,54 @@ export namespace Node { } } +export class NodeState extends jspb.Message { + getVersion(): string; + setVersion(value: string): void; + + getNodePubKey(): string; + setNodePubKey(value: string): void; + + clearAddressesList(): void; + getAddressesList(): Array
; + setAddressesList(value: Array
): void; + addAddresses(value?: Address, index?: number): Address; + + clearPairsList(): void; + getPairsList(): Array; + setPairsList(value: Array): void; + addPairs(value: string, index?: number): string; + + getRaidenAddress(): string; + setRaidenAddress(value: string): void; + + getLndBtcPubKey(): string; + setLndBtcPubKey(value: string): void; + + getLndLtcPubKey(): string; + setLndLtcPubKey(value: string): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): NodeState.AsObject; + static toObject(includeInstance: boolean, msg: NodeState): NodeState.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: NodeState, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): NodeState; + static deserializeBinaryFromReader(message: NodeState, reader: jspb.BinaryReader): NodeState; +} + +export namespace NodeState { + export type AsObject = { + version: string, + nodePubKey: string, + addressesList: Array, + pairsList: Array, + raidenAddress: string, + lndBtcPubKey: string, + lndLtcPubKey: string, + } +} + export class PingPacket extends jspb.Message { getId(): string; setId(value: string): void; @@ -137,9 +185,6 @@ export class OrderPacket extends jspb.Message { getId(): string; setId(value: string): void; - getHash(): string; - setHash(value: string): void; - hasOrder(): boolean; clearOrder(): void; getOrder(): Order | undefined; @@ -158,7 +203,6 @@ export class OrderPacket extends jspb.Message { export namespace OrderPacket { export type AsObject = { id: string, - hash: string, order?: Order.AsObject, } } @@ -167,9 +211,6 @@ export class OrderInvalidationPacket extends jspb.Message { getId(): string; setId(value: string): void; - getHash(): string; - setHash(value: string): void; - getOrderId(): string; setOrderId(value: string): void; @@ -192,7 +233,6 @@ export class OrderInvalidationPacket extends jspb.Message { export namespace OrderInvalidationPacket { export type AsObject = { id: string, - hash: string, orderId: string, pairId: string, quantity: number, @@ -203,9 +243,6 @@ export class GetOrdersPacket extends jspb.Message { getId(): string; setId(value: string): void; - getHash(): string; - setHash(value: string): void; - clearPairIdsList(): void; getPairIdsList(): Array; setPairIdsList(value: Array): void; @@ -224,7 +261,6 @@ export class GetOrdersPacket extends jspb.Message { export namespace GetOrdersPacket { export type AsObject = { id: string, - hash: string, pairIdsList: Array, } } @@ -236,9 +272,6 @@ export class OrdersPacket extends jspb.Message { getReqId(): string; setReqId(value: string): void; - getHash(): string; - setHash(value: string): void; - clearOrdersList(): void; getOrdersList(): Array; setOrdersList(value: Array): void; @@ -258,24 +291,14 @@ export namespace OrdersPacket { export type AsObject = { id: string, reqId: string, - hash: string, ordersList: Array, } } -export class HelloPacket extends jspb.Message { +export class NodeStateUpdatePacket extends jspb.Message { getId(): string; setId(value: string): void; - getHash(): string; - setHash(value: string): void; - - getVersion(): string; - setVersion(value: string): void; - - getNodePubKey(): string; - setNodePubKey(value: string): void; - clearAddressesList(): void; getAddressesList(): Array
; setAddressesList(value: Array
): void; @@ -289,42 +312,102 @@ export class HelloPacket extends jspb.Message { getRaidenAddress(): string; setRaidenAddress(value: string): void; - getLndbtcPubKey(): string; - setLndbtcPubKey(value: string): void; + getLndBtcPubKey(): string; + setLndBtcPubKey(value: string): void; - getLndltcPubKey(): string; - setLndltcPubKey(value: string): void; + getLndLtcPubKey(): string; + setLndLtcPubKey(value: string): void; serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): HelloPacket.AsObject; - static toObject(includeInstance: boolean, msg: HelloPacket): HelloPacket.AsObject; + toObject(includeInstance?: boolean): NodeStateUpdatePacket.AsObject; + static toObject(includeInstance: boolean, msg: NodeStateUpdatePacket): NodeStateUpdatePacket.AsObject; static extensions: {[key: number]: jspb.ExtensionFieldInfo}; static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; - static serializeBinaryToWriter(message: HelloPacket, writer: jspb.BinaryWriter): void; - static deserializeBinary(bytes: Uint8Array): HelloPacket; - static deserializeBinaryFromReader(message: HelloPacket, reader: jspb.BinaryReader): HelloPacket; + static serializeBinaryToWriter(message: NodeStateUpdatePacket, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): NodeStateUpdatePacket; + static deserializeBinaryFromReader(message: NodeStateUpdatePacket, reader: jspb.BinaryReader): NodeStateUpdatePacket; } -export namespace HelloPacket { +export namespace NodeStateUpdatePacket { export type AsObject = { id: string, - hash: string, - version: string, - nodePubKey: string, addressesList: Array, pairsList: Array, raidenAddress: string, - lndbtcPubKey: string, - lndltcPubKey: string, + lndBtcPubKey: string, + lndLtcPubKey: string, } } -export class DisconnectingPacket extends jspb.Message { +export class SessionInitPacket extends jspb.Message { + getId(): string; + setId(value: string): void; + + getSign(): string; + setSign(value: string): void; + + getPeerPubKey(): string; + setPeerPubKey(value: string): void; + + getEphemeralPubKey(): string; + setEphemeralPubKey(value: string): void; + + hasNodeState(): boolean; + clearNodeState(): void; + getNodeState(): NodeState | undefined; + setNodeState(value?: NodeState): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): SessionInitPacket.AsObject; + static toObject(includeInstance: boolean, msg: SessionInitPacket): SessionInitPacket.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: SessionInitPacket, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): SessionInitPacket; + static deserializeBinaryFromReader(message: SessionInitPacket, reader: jspb.BinaryReader): SessionInitPacket; +} + +export namespace SessionInitPacket { + export type AsObject = { + id: string, + sign: string, + peerPubKey: string, + ephemeralPubKey: string, + nodeState?: NodeState.AsObject, + } +} + +export class SessionAckPacket extends jspb.Message { getId(): string; setId(value: string): void; - getHash(): string; - setHash(value: string): void; + getReqId(): string; + setReqId(value: string): void; + + getEphemeralPubKey(): string; + setEphemeralPubKey(value: string): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): SessionAckPacket.AsObject; + static toObject(includeInstance: boolean, msg: SessionAckPacket): SessionAckPacket.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: SessionAckPacket, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): SessionAckPacket; + static deserializeBinaryFromReader(message: SessionAckPacket, reader: jspb.BinaryReader): SessionAckPacket; +} + +export namespace SessionAckPacket { + export type AsObject = { + id: string, + reqId: string, + ephemeralPubKey: string, + } +} + +export class DisconnectingPacket extends jspb.Message { + getId(): string; + setId(value: string): void; getReason(): number; setReason(value: number): void; @@ -345,7 +428,6 @@ export class DisconnectingPacket extends jspb.Message { export namespace DisconnectingPacket { export type AsObject = { id: string, - hash: string, reason: number, payload: string, } @@ -378,9 +460,6 @@ export class NodesPacket extends jspb.Message { getReqId(): string; setReqId(value: string): void; - getHash(): string; - setHash(value: string): void; - clearNodesList(): void; getNodesList(): Array; setNodesList(value: Array): void; @@ -400,7 +479,6 @@ export namespace NodesPacket { export type AsObject = { id: string, reqId: string, - hash: string, nodesList: Array, } } @@ -409,9 +487,6 @@ export class SwapRequestPacket extends jspb.Message { getId(): string; setId(value: string): void; - getHash(): string; - setHash(value: string): void; - getProposedQuantity(): number; setProposedQuantity(value: number): void; @@ -440,7 +515,6 @@ export class SwapRequestPacket extends jspb.Message { export namespace SwapRequestPacket { export type AsObject = { id: string, - hash: string, proposedQuantity: number, pairId: string, orderId: string, @@ -456,9 +530,6 @@ export class SwapAcceptedPacket extends jspb.Message { getReqId(): string; setReqId(value: string): void; - getHash(): string; - setHash(value: string): void; - getRHash(): string; setRHash(value: string): void; @@ -482,7 +553,6 @@ export namespace SwapAcceptedPacket { export type AsObject = { id: string, reqId: string, - hash: string, rHash: string, quantity: number, makerCltvDelta: number, @@ -496,9 +566,6 @@ export class SwapCompletePacket extends jspb.Message { getReqId(): string; setReqId(value: string): void; - getHash(): string; - setHash(value: string): void; - getRHash(): string; setRHash(value: string): void; @@ -516,7 +583,6 @@ export namespace SwapCompletePacket { export type AsObject = { id: string, reqId: string, - hash: string, rHash: string, } } @@ -528,9 +594,6 @@ export class SwapFailedPacket extends jspb.Message { getReqId(): string; setReqId(value: string): void; - getHash(): string; - setHash(value: string): void; - getRHash(): string; setRHash(value: string): void; @@ -554,7 +617,6 @@ export namespace SwapFailedPacket { export type AsObject = { id: string, reqId: string, - hash: string, rHash: string, errorMessage: string, failureReason: number, diff --git a/lib/proto/xudp2p_pb.js b/lib/proto/xudp2p_pb.js index 7de120efa..3450f7ff4 100644 --- a/lib/proto/xudp2p_pb.js +++ b/lib/proto/xudp2p_pb.js @@ -15,8 +15,9 @@ goog.exportSymbol('proto.xudp2p.Address', null, global); goog.exportSymbol('proto.xudp2p.DisconnectingPacket', null, global); goog.exportSymbol('proto.xudp2p.GetNodesPacket', null, global); goog.exportSymbol('proto.xudp2p.GetOrdersPacket', null, global); -goog.exportSymbol('proto.xudp2p.HelloPacket', null, global); goog.exportSymbol('proto.xudp2p.Node', null, global); +goog.exportSymbol('proto.xudp2p.NodeState', null, global); +goog.exportSymbol('proto.xudp2p.NodeStateUpdatePacket', null, global); goog.exportSymbol('proto.xudp2p.NodesPacket', null, global); goog.exportSymbol('proto.xudp2p.Order', null, global); goog.exportSymbol('proto.xudp2p.OrderInvalidationPacket', null, global); @@ -24,6 +25,8 @@ goog.exportSymbol('proto.xudp2p.OrderPacket', null, global); goog.exportSymbol('proto.xudp2p.OrdersPacket', null, global); goog.exportSymbol('proto.xudp2p.PingPacket', null, global); goog.exportSymbol('proto.xudp2p.PongPacket', null, global); +goog.exportSymbol('proto.xudp2p.SessionAckPacket', null, global); +goog.exportSymbol('proto.xudp2p.SessionInitPacket', null, global); goog.exportSymbol('proto.xudp2p.SwapAcceptedPacket', null, global); goog.exportSymbol('proto.xudp2p.SwapCompletePacket', null, global); goog.exportSymbol('proto.xudp2p.SwapFailedPacket', null, global); @@ -645,6 +648,350 @@ proto.xudp2p.Node.prototype.clearAddressesList = function() { +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.xudp2p.NodeState = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.NodeState.repeatedFields_, null); +}; +goog.inherits(proto.xudp2p.NodeState, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.xudp2p.NodeState.displayName = 'proto.xudp2p.NodeState'; +} +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.xudp2p.NodeState.repeatedFields_ = [3,4]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.xudp2p.NodeState.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.NodeState.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.xudp2p.NodeState} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.xudp2p.NodeState.toObject = function(includeInstance, msg) { + var f, obj = { + version: jspb.Message.getFieldWithDefault(msg, 1, ""), + nodePubKey: jspb.Message.getFieldWithDefault(msg, 2, ""), + addressesList: jspb.Message.toObjectList(msg.getAddressesList(), + proto.xudp2p.Address.toObject, includeInstance), + pairsList: jspb.Message.getRepeatedField(msg, 4), + raidenAddress: jspb.Message.getFieldWithDefault(msg, 5, ""), + lndBtcPubKey: jspb.Message.getFieldWithDefault(msg, 6, ""), + lndLtcPubKey: jspb.Message.getFieldWithDefault(msg, 7, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.xudp2p.NodeState} + */ +proto.xudp2p.NodeState.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.xudp2p.NodeState; + return proto.xudp2p.NodeState.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.xudp2p.NodeState} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.xudp2p.NodeState} + */ +proto.xudp2p.NodeState.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setVersion(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setNodePubKey(value); + break; + case 3: + var value = new proto.xudp2p.Address; + reader.readMessage(value,proto.xudp2p.Address.deserializeBinaryFromReader); + msg.addAddresses(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.addPairs(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setRaidenAddress(value); + break; + case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setLndBtcPubKey(value); + break; + case 7: + var value = /** @type {string} */ (reader.readString()); + msg.setLndLtcPubKey(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.xudp2p.NodeState.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.xudp2p.NodeState.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.xudp2p.NodeState} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.xudp2p.NodeState.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getVersion(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getNodePubKey(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getAddressesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 3, + f, + proto.xudp2p.Address.serializeBinaryToWriter + ); + } + f = message.getPairsList(); + if (f.length > 0) { + writer.writeRepeatedString( + 4, + f + ); + } + f = message.getRaidenAddress(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getLndBtcPubKey(); + if (f.length > 0) { + writer.writeString( + 6, + f + ); + } + f = message.getLndLtcPubKey(); + if (f.length > 0) { + writer.writeString( + 7, + f + ); + } +}; + + +/** + * optional string version = 1; + * @return {string} + */ +proto.xudp2p.NodeState.prototype.getVersion = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.NodeState.prototype.setVersion = function(value) { + jspb.Message.setField(this, 1, value); +}; + + +/** + * optional string node_pub_key = 2; + * @return {string} + */ +proto.xudp2p.NodeState.prototype.getNodePubKey = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.NodeState.prototype.setNodePubKey = function(value) { + jspb.Message.setField(this, 2, value); +}; + + +/** + * repeated Address addresses = 3; + * @return {!Array.} + */ +proto.xudp2p.NodeState.prototype.getAddressesList = function() { + return /** @type{!Array.} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Address, 3)); +}; + + +/** @param {!Array.} value */ +proto.xudp2p.NodeState.prototype.setAddressesList = function(value) { + jspb.Message.setRepeatedWrapperField(this, 3, value); +}; + + +/** + * @param {!proto.xudp2p.Address=} opt_value + * @param {number=} opt_index + * @return {!proto.xudp2p.Address} + */ +proto.xudp2p.NodeState.prototype.addAddresses = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.xudp2p.Address, opt_index); +}; + + +proto.xudp2p.NodeState.prototype.clearAddressesList = function() { + this.setAddressesList([]); +}; + + +/** + * repeated string pairs = 4; + * @return {!Array.} + */ +proto.xudp2p.NodeState.prototype.getPairsList = function() { + return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 4)); +}; + + +/** @param {!Array.} value */ +proto.xudp2p.NodeState.prototype.setPairsList = function(value) { + jspb.Message.setField(this, 4, value || []); +}; + + +/** + * @param {!string} value + * @param {number=} opt_index + */ +proto.xudp2p.NodeState.prototype.addPairs = function(value, opt_index) { + jspb.Message.addToRepeatedField(this, 4, value, opt_index); +}; + + +proto.xudp2p.NodeState.prototype.clearPairsList = function() { + this.setPairsList([]); +}; + + +/** + * optional string raiden_address = 5; + * @return {string} + */ +proto.xudp2p.NodeState.prototype.getRaidenAddress = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.NodeState.prototype.setRaidenAddress = function(value) { + jspb.Message.setField(this, 5, value); +}; + + +/** + * optional string lnd_btc_pub_key = 6; + * @return {string} + */ +proto.xudp2p.NodeState.prototype.getLndBtcPubKey = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.NodeState.prototype.setLndBtcPubKey = function(value) { + jspb.Message.setField(this, 6, value); +}; + + +/** + * optional string lnd_ltc_pub_key = 7; + * @return {string} + */ +proto.xudp2p.NodeState.prototype.getLndLtcPubKey = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.NodeState.prototype.setLndLtcPubKey = function(value) { + jspb.Message.setField(this, 7, value); +}; + + + /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a @@ -1003,7 +1350,6 @@ proto.xudp2p.OrderPacket.prototype.toObject = function(opt_includeInstance) { proto.xudp2p.OrderPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - hash: jspb.Message.getFieldWithDefault(msg, 2, ""), order: (f = msg.getOrder()) && proto.xudp2p.Order.toObject(includeInstance, f) }; @@ -1046,10 +1392,6 @@ proto.xudp2p.OrderPacket.deserializeBinaryFromReader = function(msg, reader) { msg.setId(value); break; case 2: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 3: var value = new proto.xudp2p.Order; reader.readMessage(value,proto.xudp2p.Order.deserializeBinaryFromReader); msg.setOrder(value); @@ -1090,17 +1432,10 @@ proto.xudp2p.OrderPacket.serializeBinaryToWriter = function(message, writer) { f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 2, - f - ); - } f = message.getOrder(); if (f != null) { writer.writeMessage( - 3, + 2, f, proto.xudp2p.Order.serializeBinaryToWriter ); @@ -1124,33 +1459,18 @@ proto.xudp2p.OrderPacket.prototype.setId = function(value) { /** - * optional string hash = 2; - * @return {string} - */ -proto.xudp2p.OrderPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.OrderPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 2, value); -}; - - -/** - * optional Order order = 3; + * optional Order order = 2; * @return {?proto.xudp2p.Order} */ proto.xudp2p.OrderPacket.prototype.getOrder = function() { return /** @type{?proto.xudp2p.Order} */ ( - jspb.Message.getWrapperField(this, proto.xudp2p.Order, 3)); + jspb.Message.getWrapperField(this, proto.xudp2p.Order, 2)); }; /** @param {?proto.xudp2p.Order|undefined} value */ proto.xudp2p.OrderPacket.prototype.setOrder = function(value) { - jspb.Message.setWrapperField(this, 3, value); + jspb.Message.setWrapperField(this, 2, value); }; @@ -1164,7 +1484,7 @@ proto.xudp2p.OrderPacket.prototype.clearOrder = function() { * @return {!boolean} */ proto.xudp2p.OrderPacket.prototype.hasOrder = function() { - return jspb.Message.getField(this, 3) != null; + return jspb.Message.getField(this, 2) != null; }; @@ -1199,8 +1519,238 @@ if (jspb.Message.GENERATE_TO_OBJECT) { * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ -proto.xudp2p.OrderInvalidationPacket.prototype.toObject = function(opt_includeInstance) { - return proto.xudp2p.OrderInvalidationPacket.toObject(opt_includeInstance, this); +proto.xudp2p.OrderInvalidationPacket.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.OrderInvalidationPacket.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.xudp2p.OrderInvalidationPacket} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.xudp2p.OrderInvalidationPacket.toObject = function(includeInstance, msg) { + var f, obj = { + id: jspb.Message.getFieldWithDefault(msg, 1, ""), + orderId: jspb.Message.getFieldWithDefault(msg, 2, ""), + pairId: jspb.Message.getFieldWithDefault(msg, 3, ""), + quantity: +jspb.Message.getFieldWithDefault(msg, 4, 0.0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.xudp2p.OrderInvalidationPacket} + */ +proto.xudp2p.OrderInvalidationPacket.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.xudp2p.OrderInvalidationPacket; + return proto.xudp2p.OrderInvalidationPacket.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.xudp2p.OrderInvalidationPacket} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.xudp2p.OrderInvalidationPacket} + */ +proto.xudp2p.OrderInvalidationPacket.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setId(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setOrderId(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setPairId(value); + break; + case 4: + var value = /** @type {number} */ (reader.readDouble()); + msg.setQuantity(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.xudp2p.OrderInvalidationPacket.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.xudp2p.OrderInvalidationPacket.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.xudp2p.OrderInvalidationPacket} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.xudp2p.OrderInvalidationPacket.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getId(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getOrderId(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getPairId(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getQuantity(); + if (f !== 0.0) { + writer.writeDouble( + 4, + f + ); + } +}; + + +/** + * optional string id = 1; + * @return {string} + */ +proto.xudp2p.OrderInvalidationPacket.prototype.getId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.OrderInvalidationPacket.prototype.setId = function(value) { + jspb.Message.setField(this, 1, value); +}; + + +/** + * optional string order_id = 2; + * @return {string} + */ +proto.xudp2p.OrderInvalidationPacket.prototype.getOrderId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.OrderInvalidationPacket.prototype.setOrderId = function(value) { + jspb.Message.setField(this, 2, value); +}; + + +/** + * optional string pair_id = 3; + * @return {string} + */ +proto.xudp2p.OrderInvalidationPacket.prototype.getPairId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** @param {string} value */ +proto.xudp2p.OrderInvalidationPacket.prototype.setPairId = function(value) { + jspb.Message.setField(this, 3, value); +}; + + +/** + * optional double quantity = 4; + * @return {number} + */ +proto.xudp2p.OrderInvalidationPacket.prototype.getQuantity = function() { + return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 4, 0.0)); +}; + + +/** @param {number} value */ +proto.xudp2p.OrderInvalidationPacket.prototype.setQuantity = function(value) { + jspb.Message.setField(this, 4, value); +}; + + + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.xudp2p.GetOrdersPacket = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.GetOrdersPacket.repeatedFields_, null); +}; +goog.inherits(proto.xudp2p.GetOrdersPacket, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.xudp2p.GetOrdersPacket.displayName = 'proto.xudp2p.GetOrdersPacket'; +} +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.xudp2p.GetOrdersPacket.repeatedFields_ = [2]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.xudp2p.GetOrdersPacket.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.GetOrdersPacket.toObject(opt_includeInstance, this); }; @@ -1209,17 +1759,14 @@ proto.xudp2p.OrderInvalidationPacket.prototype.toObject = function(opt_includeIn * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.xudp2p.OrderInvalidationPacket} msg The msg instance to transform. + * @param {!proto.xudp2p.GetOrdersPacket} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.OrderInvalidationPacket.toObject = function(includeInstance, msg) { +proto.xudp2p.GetOrdersPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - hash: jspb.Message.getFieldWithDefault(msg, 2, ""), - orderId: jspb.Message.getFieldWithDefault(msg, 3, ""), - pairId: jspb.Message.getFieldWithDefault(msg, 4, ""), - quantity: +jspb.Message.getFieldWithDefault(msg, 5, 0.0) + pairIdsList: jspb.Message.getRepeatedField(msg, 2) }; if (includeInstance) { @@ -1233,23 +1780,23 @@ proto.xudp2p.OrderInvalidationPacket.toObject = function(includeInstance, msg) { /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.xudp2p.OrderInvalidationPacket} + * @return {!proto.xudp2p.GetOrdersPacket} */ -proto.xudp2p.OrderInvalidationPacket.deserializeBinary = function(bytes) { +proto.xudp2p.GetOrdersPacket.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.xudp2p.OrderInvalidationPacket; - return proto.xudp2p.OrderInvalidationPacket.deserializeBinaryFromReader(msg, reader); + var msg = new proto.xudp2p.GetOrdersPacket; + return proto.xudp2p.GetOrdersPacket.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.xudp2p.OrderInvalidationPacket} msg The message object to deserialize into. + * @param {!proto.xudp2p.GetOrdersPacket} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.xudp2p.OrderInvalidationPacket} + * @return {!proto.xudp2p.GetOrdersPacket} */ -proto.xudp2p.OrderInvalidationPacket.deserializeBinaryFromReader = function(msg, reader) { +proto.xudp2p.GetOrdersPacket.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -1262,19 +1809,7 @@ proto.xudp2p.OrderInvalidationPacket.deserializeBinaryFromReader = function(msg, break; case 2: var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 3: - var value = /** @type {string} */ (reader.readString()); - msg.setOrderId(value); - break; - case 4: - var value = /** @type {string} */ (reader.readString()); - msg.setPairId(value); - break; - case 5: - var value = /** @type {number} */ (reader.readDouble()); - msg.setQuantity(value); + msg.addPairIds(value); break; default: reader.skipField(); @@ -1289,9 +1824,9 @@ proto.xudp2p.OrderInvalidationPacket.deserializeBinaryFromReader = function(msg, * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.xudp2p.OrderInvalidationPacket.prototype.serializeBinary = function() { +proto.xudp2p.GetOrdersPacket.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.xudp2p.OrderInvalidationPacket.serializeBinaryToWriter(this, writer); + proto.xudp2p.GetOrdersPacket.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -1299,11 +1834,11 @@ proto.xudp2p.OrderInvalidationPacket.prototype.serializeBinary = function() { /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.xudp2p.OrderInvalidationPacket} message + * @param {!proto.xudp2p.GetOrdersPacket} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.OrderInvalidationPacket.serializeBinaryToWriter = function(message, writer) { +proto.xudp2p.GetOrdersPacket.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getId(); if (f.length > 0) { @@ -1312,34 +1847,13 @@ proto.xudp2p.OrderInvalidationPacket.serializeBinaryToWriter = function(message, f ); } - f = message.getHash(); + f = message.getPairIdsList(); if (f.length > 0) { - writer.writeString( + writer.writeRepeatedString( 2, f ); } - f = message.getOrderId(); - if (f.length > 0) { - writer.writeString( - 3, - f - ); - } - f = message.getPairId(); - if (f.length > 0) { - writer.writeString( - 4, - f - ); - } - f = message.getQuantity(); - if (f !== 0.0) { - writer.writeDouble( - 5, - f - ); - } }; @@ -1347,74 +1861,43 @@ proto.xudp2p.OrderInvalidationPacket.serializeBinaryToWriter = function(message, * optional string id = 1; * @return {string} */ -proto.xudp2p.OrderInvalidationPacket.prototype.getId = function() { +proto.xudp2p.GetOrdersPacket.prototype.getId = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ -proto.xudp2p.OrderInvalidationPacket.prototype.setId = function(value) { +proto.xudp2p.GetOrdersPacket.prototype.setId = function(value) { jspb.Message.setField(this, 1, value); }; /** - * optional string hash = 2; - * @return {string} - */ -proto.xudp2p.OrderInvalidationPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.OrderInvalidationPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 2, value); -}; - - -/** - * optional string order_id = 3; - * @return {string} - */ -proto.xudp2p.OrderInvalidationPacket.prototype.getOrderId = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.OrderInvalidationPacket.prototype.setOrderId = function(value) { - jspb.Message.setField(this, 3, value); -}; - - -/** - * optional string pair_id = 4; - * @return {string} + * repeated string pair_ids = 2; + * @return {!Array.} */ -proto.xudp2p.OrderInvalidationPacket.prototype.getPairId = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +proto.xudp2p.GetOrdersPacket.prototype.getPairIdsList = function() { + return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 2)); }; -/** @param {string} value */ -proto.xudp2p.OrderInvalidationPacket.prototype.setPairId = function(value) { - jspb.Message.setField(this, 4, value); +/** @param {!Array.} value */ +proto.xudp2p.GetOrdersPacket.prototype.setPairIdsList = function(value) { + jspb.Message.setField(this, 2, value || []); }; /** - * optional double quantity = 5; - * @return {number} + * @param {!string} value + * @param {number=} opt_index */ -proto.xudp2p.OrderInvalidationPacket.prototype.getQuantity = function() { - return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 5, 0.0)); +proto.xudp2p.GetOrdersPacket.prototype.addPairIds = function(value, opt_index) { + jspb.Message.addToRepeatedField(this, 2, value, opt_index); }; -/** @param {number} value */ -proto.xudp2p.OrderInvalidationPacket.prototype.setQuantity = function(value) { - jspb.Message.setField(this, 5, value); +proto.xudp2p.GetOrdersPacket.prototype.clearPairIdsList = function() { + this.setPairIdsList([]); }; @@ -1429,19 +1912,19 @@ proto.xudp2p.OrderInvalidationPacket.prototype.setQuantity = function(value) { * @extends {jspb.Message} * @constructor */ -proto.xudp2p.GetOrdersPacket = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.GetOrdersPacket.repeatedFields_, null); +proto.xudp2p.OrdersPacket = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.OrdersPacket.repeatedFields_, null); }; -goog.inherits(proto.xudp2p.GetOrdersPacket, jspb.Message); +goog.inherits(proto.xudp2p.OrdersPacket, jspb.Message); if (goog.DEBUG && !COMPILED) { - proto.xudp2p.GetOrdersPacket.displayName = 'proto.xudp2p.GetOrdersPacket'; + proto.xudp2p.OrdersPacket.displayName = 'proto.xudp2p.OrdersPacket'; } /** * List of repeated fields within this message type. * @private {!Array} * @const */ -proto.xudp2p.GetOrdersPacket.repeatedFields_ = [3]; +proto.xudp2p.OrdersPacket.repeatedFields_ = [3]; @@ -1456,8 +1939,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) { * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ -proto.xudp2p.GetOrdersPacket.prototype.toObject = function(opt_includeInstance) { - return proto.xudp2p.GetOrdersPacket.toObject(opt_includeInstance, this); +proto.xudp2p.OrdersPacket.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.OrdersPacket.toObject(opt_includeInstance, this); }; @@ -1466,15 +1949,16 @@ proto.xudp2p.GetOrdersPacket.prototype.toObject = function(opt_includeInstance) * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.xudp2p.GetOrdersPacket} msg The msg instance to transform. + * @param {!proto.xudp2p.OrdersPacket} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.GetOrdersPacket.toObject = function(includeInstance, msg) { +proto.xudp2p.OrdersPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - hash: jspb.Message.getFieldWithDefault(msg, 2, ""), - pairIdsList: jspb.Message.getRepeatedField(msg, 3) + reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), + ordersList: jspb.Message.toObjectList(msg.getOrdersList(), + proto.xudp2p.Order.toObject, includeInstance) }; if (includeInstance) { @@ -1488,23 +1972,23 @@ proto.xudp2p.GetOrdersPacket.toObject = function(includeInstance, msg) { /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.xudp2p.GetOrdersPacket} + * @return {!proto.xudp2p.OrdersPacket} */ -proto.xudp2p.GetOrdersPacket.deserializeBinary = function(bytes) { +proto.xudp2p.OrdersPacket.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.xudp2p.GetOrdersPacket; - return proto.xudp2p.GetOrdersPacket.deserializeBinaryFromReader(msg, reader); + var msg = new proto.xudp2p.OrdersPacket; + return proto.xudp2p.OrdersPacket.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.xudp2p.GetOrdersPacket} msg The message object to deserialize into. + * @param {!proto.xudp2p.OrdersPacket} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.xudp2p.GetOrdersPacket} + * @return {!proto.xudp2p.OrdersPacket} */ -proto.xudp2p.GetOrdersPacket.deserializeBinaryFromReader = function(msg, reader) { +proto.xudp2p.OrdersPacket.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -1517,11 +2001,12 @@ proto.xudp2p.GetOrdersPacket.deserializeBinaryFromReader = function(msg, reader) break; case 2: var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); + msg.setReqId(value); break; case 3: - var value = /** @type {string} */ (reader.readString()); - msg.addPairIds(value); + var value = new proto.xudp2p.Order; + reader.readMessage(value,proto.xudp2p.Order.deserializeBinaryFromReader); + msg.addOrders(value); break; default: reader.skipField(); @@ -1536,9 +2021,9 @@ proto.xudp2p.GetOrdersPacket.deserializeBinaryFromReader = function(msg, reader) * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.xudp2p.GetOrdersPacket.prototype.serializeBinary = function() { +proto.xudp2p.OrdersPacket.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.xudp2p.GetOrdersPacket.serializeBinaryToWriter(this, writer); + proto.xudp2p.OrdersPacket.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -1546,11 +2031,11 @@ proto.xudp2p.GetOrdersPacket.prototype.serializeBinary = function() { /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.xudp2p.GetOrdersPacket} message + * @param {!proto.xudp2p.OrdersPacket} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.GetOrdersPacket.serializeBinaryToWriter = function(message, writer) { +proto.xudp2p.OrdersPacket.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getId(); if (f.length > 0) { @@ -1559,18 +2044,19 @@ proto.xudp2p.GetOrdersPacket.serializeBinaryToWriter = function(message, writer) f ); } - f = message.getHash(); + f = message.getReqId(); if (f.length > 0) { writer.writeString( 2, f ); } - f = message.getPairIdsList(); + f = message.getOrdersList(); if (f.length > 0) { - writer.writeRepeatedString( + writer.writeRepeatedMessage( 3, - f + f, + proto.xudp2p.Order.serializeBinaryToWriter ); } }; @@ -1580,58 +2066,60 @@ proto.xudp2p.GetOrdersPacket.serializeBinaryToWriter = function(message, writer) * optional string id = 1; * @return {string} */ -proto.xudp2p.GetOrdersPacket.prototype.getId = function() { +proto.xudp2p.OrdersPacket.prototype.getId = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ -proto.xudp2p.GetOrdersPacket.prototype.setId = function(value) { +proto.xudp2p.OrdersPacket.prototype.setId = function(value) { jspb.Message.setField(this, 1, value); }; /** - * optional string hash = 2; + * optional string req_id = 2; * @return {string} */ -proto.xudp2p.GetOrdersPacket.prototype.getHash = function() { +proto.xudp2p.OrdersPacket.prototype.getReqId = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); }; /** @param {string} value */ -proto.xudp2p.GetOrdersPacket.prototype.setHash = function(value) { +proto.xudp2p.OrdersPacket.prototype.setReqId = function(value) { jspb.Message.setField(this, 2, value); }; /** - * repeated string pair_ids = 3; - * @return {!Array.} + * repeated Order orders = 3; + * @return {!Array.} */ -proto.xudp2p.GetOrdersPacket.prototype.getPairIdsList = function() { - return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 3)); +proto.xudp2p.OrdersPacket.prototype.getOrdersList = function() { + return /** @type{!Array.} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Order, 3)); }; -/** @param {!Array.} value */ -proto.xudp2p.GetOrdersPacket.prototype.setPairIdsList = function(value) { - jspb.Message.setField(this, 3, value || []); +/** @param {!Array.} value */ +proto.xudp2p.OrdersPacket.prototype.setOrdersList = function(value) { + jspb.Message.setRepeatedWrapperField(this, 3, value); }; /** - * @param {!string} value + * @param {!proto.xudp2p.Order=} opt_value * @param {number=} opt_index + * @return {!proto.xudp2p.Order} */ -proto.xudp2p.GetOrdersPacket.prototype.addPairIds = function(value, opt_index) { - jspb.Message.addToRepeatedField(this, 3, value, opt_index); +proto.xudp2p.OrdersPacket.prototype.addOrders = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.xudp2p.Order, opt_index); }; -proto.xudp2p.GetOrdersPacket.prototype.clearPairIdsList = function() { - this.setPairIdsList([]); +proto.xudp2p.OrdersPacket.prototype.clearOrdersList = function() { + this.setOrdersList([]); }; @@ -1646,19 +2134,19 @@ proto.xudp2p.GetOrdersPacket.prototype.clearPairIdsList = function() { * @extends {jspb.Message} * @constructor */ -proto.xudp2p.OrdersPacket = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.OrdersPacket.repeatedFields_, null); +proto.xudp2p.NodeStateUpdatePacket = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.NodeStateUpdatePacket.repeatedFields_, null); }; -goog.inherits(proto.xudp2p.OrdersPacket, jspb.Message); +goog.inherits(proto.xudp2p.NodeStateUpdatePacket, jspb.Message); if (goog.DEBUG && !COMPILED) { - proto.xudp2p.OrdersPacket.displayName = 'proto.xudp2p.OrdersPacket'; + proto.xudp2p.NodeStateUpdatePacket.displayName = 'proto.xudp2p.NodeStateUpdatePacket'; } /** * List of repeated fields within this message type. * @private {!Array} * @const */ -proto.xudp2p.OrdersPacket.repeatedFields_ = [4]; +proto.xudp2p.NodeStateUpdatePacket.repeatedFields_ = [2,3]; @@ -1673,8 +2161,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) { * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ -proto.xudp2p.OrdersPacket.prototype.toObject = function(opt_includeInstance) { - return proto.xudp2p.OrdersPacket.toObject(opt_includeInstance, this); +proto.xudp2p.NodeStateUpdatePacket.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.NodeStateUpdatePacket.toObject(opt_includeInstance, this); }; @@ -1683,17 +2171,19 @@ proto.xudp2p.OrdersPacket.prototype.toObject = function(opt_includeInstance) { * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.xudp2p.OrdersPacket} msg The msg instance to transform. + * @param {!proto.xudp2p.NodeStateUpdatePacket} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.OrdersPacket.toObject = function(includeInstance, msg) { +proto.xudp2p.NodeStateUpdatePacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), - hash: jspb.Message.getFieldWithDefault(msg, 3, ""), - ordersList: jspb.Message.toObjectList(msg.getOrdersList(), - proto.xudp2p.Order.toObject, includeInstance) + addressesList: jspb.Message.toObjectList(msg.getAddressesList(), + proto.xudp2p.Address.toObject, includeInstance), + pairsList: jspb.Message.getRepeatedField(msg, 3), + raidenAddress: jspb.Message.getFieldWithDefault(msg, 4, ""), + lndBtcPubKey: jspb.Message.getFieldWithDefault(msg, 5, ""), + lndLtcPubKey: jspb.Message.getFieldWithDefault(msg, 6, "") }; if (includeInstance) { @@ -1707,23 +2197,23 @@ proto.xudp2p.OrdersPacket.toObject = function(includeInstance, msg) { /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.xudp2p.OrdersPacket} + * @return {!proto.xudp2p.NodeStateUpdatePacket} */ -proto.xudp2p.OrdersPacket.deserializeBinary = function(bytes) { +proto.xudp2p.NodeStateUpdatePacket.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.xudp2p.OrdersPacket; - return proto.xudp2p.OrdersPacket.deserializeBinaryFromReader(msg, reader); + var msg = new proto.xudp2p.NodeStateUpdatePacket; + return proto.xudp2p.NodeStateUpdatePacket.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.xudp2p.OrdersPacket} msg The message object to deserialize into. + * @param {!proto.xudp2p.NodeStateUpdatePacket} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.xudp2p.OrdersPacket} + * @return {!proto.xudp2p.NodeStateUpdatePacket} */ -proto.xudp2p.OrdersPacket.deserializeBinaryFromReader = function(msg, reader) { +proto.xudp2p.NodeStateUpdatePacket.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -1735,17 +2225,25 @@ proto.xudp2p.OrdersPacket.deserializeBinaryFromReader = function(msg, reader) { msg.setId(value); break; case 2: - var value = /** @type {string} */ (reader.readString()); - msg.setReqId(value); + var value = new proto.xudp2p.Address; + reader.readMessage(value,proto.xudp2p.Address.deserializeBinaryFromReader); + msg.addAddresses(value); break; case 3: var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); + msg.addPairs(value); break; case 4: - var value = new proto.xudp2p.Order; - reader.readMessage(value,proto.xudp2p.Order.deserializeBinaryFromReader); - msg.addOrders(value); + var value = /** @type {string} */ (reader.readString()); + msg.setRaidenAddress(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setLndBtcPubKey(value); + break; + case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setLndLtcPubKey(value); break; default: reader.skipField(); @@ -1760,9 +2258,9 @@ proto.xudp2p.OrdersPacket.deserializeBinaryFromReader = function(msg, reader) { * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.xudp2p.OrdersPacket.prototype.serializeBinary = function() { +proto.xudp2p.NodeStateUpdatePacket.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.xudp2p.OrdersPacket.serializeBinaryToWriter(this, writer); + proto.xudp2p.NodeStateUpdatePacket.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -1770,11 +2268,11 @@ proto.xudp2p.OrdersPacket.prototype.serializeBinary = function() { /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.xudp2p.OrdersPacket} message + * @param {!proto.xudp2p.NodeStateUpdatePacket} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.OrdersPacket.serializeBinaryToWriter = function(message, writer) { +proto.xudp2p.NodeStateUpdatePacket.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getId(); if (f.length > 0) { @@ -1783,26 +2281,40 @@ proto.xudp2p.OrdersPacket.serializeBinaryToWriter = function(message, writer) { f ); } - f = message.getReqId(); + f = message.getAddressesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 2, + f, + proto.xudp2p.Address.serializeBinaryToWriter + ); + } + f = message.getPairsList(); + if (f.length > 0) { + writer.writeRepeatedString( + 3, + f + ); + } + f = message.getRaidenAddress(); if (f.length > 0) { writer.writeString( - 2, + 4, f ); } - f = message.getHash(); + f = message.getLndBtcPubKey(); if (f.length > 0) { writer.writeString( - 3, + 5, f ); } - f = message.getOrdersList(); + f = message.getLndLtcPubKey(); if (f.length > 0) { - writer.writeRepeatedMessage( - 4, - f, - proto.xudp2p.Order.serializeBinaryToWriter + writer.writeString( + 6, + f ); } }; @@ -1812,75 +2324,119 @@ proto.xudp2p.OrdersPacket.serializeBinaryToWriter = function(message, writer) { * optional string id = 1; * @return {string} */ -proto.xudp2p.OrdersPacket.prototype.getId = function() { +proto.xudp2p.NodeStateUpdatePacket.prototype.getId = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ -proto.xudp2p.OrdersPacket.prototype.setId = function(value) { +proto.xudp2p.NodeStateUpdatePacket.prototype.setId = function(value) { jspb.Message.setField(this, 1, value); }; /** - * optional string req_id = 2; - * @return {string} + * repeated Address addresses = 2; + * @return {!Array.} */ -proto.xudp2p.OrdersPacket.prototype.getReqId = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +proto.xudp2p.NodeStateUpdatePacket.prototype.getAddressesList = function() { + return /** @type{!Array.} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Address, 2)); }; -/** @param {string} value */ -proto.xudp2p.OrdersPacket.prototype.setReqId = function(value) { - jspb.Message.setField(this, 2, value); +/** @param {!Array.} value */ +proto.xudp2p.NodeStateUpdatePacket.prototype.setAddressesList = function(value) { + jspb.Message.setRepeatedWrapperField(this, 2, value); +}; + + +/** + * @param {!proto.xudp2p.Address=} opt_value + * @param {number=} opt_index + * @return {!proto.xudp2p.Address} + */ +proto.xudp2p.NodeStateUpdatePacket.prototype.addAddresses = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.xudp2p.Address, opt_index); +}; + + +proto.xudp2p.NodeStateUpdatePacket.prototype.clearAddressesList = function() { + this.setAddressesList([]); +}; + + +/** + * repeated string pairs = 3; + * @return {!Array.} + */ +proto.xudp2p.NodeStateUpdatePacket.prototype.getPairsList = function() { + return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 3)); +}; + + +/** @param {!Array.} value */ +proto.xudp2p.NodeStateUpdatePacket.prototype.setPairsList = function(value) { + jspb.Message.setField(this, 3, value || []); +}; + + +/** + * @param {!string} value + * @param {number=} opt_index + */ +proto.xudp2p.NodeStateUpdatePacket.prototype.addPairs = function(value, opt_index) { + jspb.Message.addToRepeatedField(this, 3, value, opt_index); +}; + + +proto.xudp2p.NodeStateUpdatePacket.prototype.clearPairsList = function() { + this.setPairsList([]); }; /** - * optional string hash = 3; + * optional string raiden_address = 4; * @return {string} */ -proto.xudp2p.OrdersPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +proto.xudp2p.NodeStateUpdatePacket.prototype.getRaidenAddress = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); }; /** @param {string} value */ -proto.xudp2p.OrdersPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 3, value); +proto.xudp2p.NodeStateUpdatePacket.prototype.setRaidenAddress = function(value) { + jspb.Message.setField(this, 4, value); }; /** - * repeated Order orders = 4; - * @return {!Array.} + * optional string lnd_btc_pub_key = 5; + * @return {string} */ -proto.xudp2p.OrdersPacket.prototype.getOrdersList = function() { - return /** @type{!Array.} */ ( - jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Order, 4)); +proto.xudp2p.NodeStateUpdatePacket.prototype.getLndBtcPubKey = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); }; -/** @param {!Array.} value */ -proto.xudp2p.OrdersPacket.prototype.setOrdersList = function(value) { - jspb.Message.setRepeatedWrapperField(this, 4, value); +/** @param {string} value */ +proto.xudp2p.NodeStateUpdatePacket.prototype.setLndBtcPubKey = function(value) { + jspb.Message.setField(this, 5, value); }; /** - * @param {!proto.xudp2p.Order=} opt_value - * @param {number=} opt_index - * @return {!proto.xudp2p.Order} + * optional string lnd_ltc_pub_key = 6; + * @return {string} */ -proto.xudp2p.OrdersPacket.prototype.addOrders = function(opt_value, opt_index) { - return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.xudp2p.Order, opt_index); +proto.xudp2p.NodeStateUpdatePacket.prototype.getLndLtcPubKey = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); }; -proto.xudp2p.OrdersPacket.prototype.clearOrdersList = function() { - this.setOrdersList([]); +/** @param {string} value */ +proto.xudp2p.NodeStateUpdatePacket.prototype.setLndLtcPubKey = function(value) { + jspb.Message.setField(this, 6, value); }; @@ -1895,20 +2451,13 @@ proto.xudp2p.OrdersPacket.prototype.clearOrdersList = function() { * @extends {jspb.Message} * @constructor */ -proto.xudp2p.HelloPacket = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, proto.xudp2p.HelloPacket.repeatedFields_, null); +proto.xudp2p.SessionInitPacket = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; -goog.inherits(proto.xudp2p.HelloPacket, jspb.Message); +goog.inherits(proto.xudp2p.SessionInitPacket, jspb.Message); if (goog.DEBUG && !COMPILED) { - proto.xudp2p.HelloPacket.displayName = 'proto.xudp2p.HelloPacket'; + proto.xudp2p.SessionInitPacket.displayName = 'proto.xudp2p.SessionInitPacket'; } -/** - * List of repeated fields within this message type. - * @private {!Array} - * @const - */ -proto.xudp2p.HelloPacket.repeatedFields_ = [5,6]; - if (jspb.Message.GENERATE_TO_OBJECT) { @@ -1922,8 +2471,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) { * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ -proto.xudp2p.HelloPacket.prototype.toObject = function(opt_includeInstance) { - return proto.xudp2p.HelloPacket.toObject(opt_includeInstance, this); +proto.xudp2p.SessionInitPacket.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.SessionInitPacket.toObject(opt_includeInstance, this); }; @@ -1932,22 +2481,17 @@ proto.xudp2p.HelloPacket.prototype.toObject = function(opt_includeInstance) { * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.xudp2p.HelloPacket} msg The msg instance to transform. + * @param {!proto.xudp2p.SessionInitPacket} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.HelloPacket.toObject = function(includeInstance, msg) { +proto.xudp2p.SessionInitPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - hash: jspb.Message.getFieldWithDefault(msg, 2, ""), - version: jspb.Message.getFieldWithDefault(msg, 3, ""), - nodePubKey: jspb.Message.getFieldWithDefault(msg, 4, ""), - addressesList: jspb.Message.toObjectList(msg.getAddressesList(), - proto.xudp2p.Address.toObject, includeInstance), - pairsList: jspb.Message.getRepeatedField(msg, 6), - raidenAddress: jspb.Message.getFieldWithDefault(msg, 7, ""), - lndbtcPubKey: jspb.Message.getFieldWithDefault(msg, 8, ""), - lndltcPubKey: jspb.Message.getFieldWithDefault(msg, 9, "") + sign: jspb.Message.getFieldWithDefault(msg, 2, ""), + peerPubKey: jspb.Message.getFieldWithDefault(msg, 3, ""), + ephemeralPubKey: jspb.Message.getFieldWithDefault(msg, 4, ""), + nodeState: (f = msg.getNodeState()) && proto.xudp2p.NodeState.toObject(includeInstance, f) }; if (includeInstance) { @@ -1961,23 +2505,23 @@ proto.xudp2p.HelloPacket.toObject = function(includeInstance, msg) { /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.xudp2p.HelloPacket} + * @return {!proto.xudp2p.SessionInitPacket} */ -proto.xudp2p.HelloPacket.deserializeBinary = function(bytes) { +proto.xudp2p.SessionInitPacket.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.xudp2p.HelloPacket; - return proto.xudp2p.HelloPacket.deserializeBinaryFromReader(msg, reader); + var msg = new proto.xudp2p.SessionInitPacket; + return proto.xudp2p.SessionInitPacket.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.xudp2p.HelloPacket} msg The message object to deserialize into. + * @param {!proto.xudp2p.SessionInitPacket} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.xudp2p.HelloPacket} + * @return {!proto.xudp2p.SessionInitPacket} */ -proto.xudp2p.HelloPacket.deserializeBinaryFromReader = function(msg, reader) { +proto.xudp2p.SessionInitPacket.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -1990,36 +2534,20 @@ proto.xudp2p.HelloPacket.deserializeBinaryFromReader = function(msg, reader) { break; case 2: var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); + msg.setSign(value); break; case 3: var value = /** @type {string} */ (reader.readString()); - msg.setVersion(value); + msg.setPeerPubKey(value); break; case 4: var value = /** @type {string} */ (reader.readString()); - msg.setNodePubKey(value); + msg.setEphemeralPubKey(value); break; case 5: - var value = new proto.xudp2p.Address; - reader.readMessage(value,proto.xudp2p.Address.deserializeBinaryFromReader); - msg.addAddresses(value); - break; - case 6: - var value = /** @type {string} */ (reader.readString()); - msg.addPairs(value); - break; - case 7: - var value = /** @type {string} */ (reader.readString()); - msg.setRaidenAddress(value); - break; - case 8: - var value = /** @type {string} */ (reader.readString()); - msg.setLndbtcPubKey(value); - break; - case 9: - var value = /** @type {string} */ (reader.readString()); - msg.setLndltcPubKey(value); + var value = new proto.xudp2p.NodeState; + reader.readMessage(value,proto.xudp2p.NodeState.deserializeBinaryFromReader); + msg.setNodeState(value); break; default: reader.skipField(); @@ -2034,9 +2562,9 @@ proto.xudp2p.HelloPacket.deserializeBinaryFromReader = function(msg, reader) { * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.xudp2p.HelloPacket.prototype.serializeBinary = function() { +proto.xudp2p.SessionInitPacket.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.xudp2p.HelloPacket.serializeBinaryToWriter(this, writer); + proto.xudp2p.SessionInitPacket.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -2044,11 +2572,11 @@ proto.xudp2p.HelloPacket.prototype.serializeBinary = function() { /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.xudp2p.HelloPacket} message + * @param {!proto.xudp2p.SessionInitPacket} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.xudp2p.HelloPacket.serializeBinaryToWriter = function(message, writer) { +proto.xudp2p.SessionInitPacket.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getId(); if (f.length > 0) { @@ -2057,61 +2585,33 @@ proto.xudp2p.HelloPacket.serializeBinaryToWriter = function(message, writer) { f ); } - f = message.getHash(); + f = message.getSign(); if (f.length > 0) { writer.writeString( 2, f ); } - f = message.getVersion(); + f = message.getPeerPubKey(); if (f.length > 0) { writer.writeString( 3, f ); } - f = message.getNodePubKey(); + f = message.getEphemeralPubKey(); if (f.length > 0) { writer.writeString( 4, f ); } - f = message.getAddressesList(); - if (f.length > 0) { - writer.writeRepeatedMessage( + f = message.getNodeState(); + if (f != null) { + writer.writeMessage( 5, f, - proto.xudp2p.Address.serializeBinaryToWriter - ); - } - f = message.getPairsList(); - if (f.length > 0) { - writer.writeRepeatedString( - 6, - f - ); - } - f = message.getRaidenAddress(); - if (f.length > 0) { - writer.writeString( - 7, - f - ); - } - f = message.getLndbtcPubKey(); - if (f.length > 0) { - writer.writeString( - 8, - f - ); - } - f = message.getLndltcPubKey(); - if (f.length > 0) { - writer.writeString( - 9, - f + proto.xudp2p.NodeState.serializeBinaryToWriter ); } }; @@ -2121,164 +2621,285 @@ proto.xudp2p.HelloPacket.serializeBinaryToWriter = function(message, writer) { * optional string id = 1; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getId = function() { +proto.xudp2p.SessionInitPacket.prototype.getId = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setId = function(value) { +proto.xudp2p.SessionInitPacket.prototype.setId = function(value) { jspb.Message.setField(this, 1, value); }; /** - * optional string hash = 2; + * optional string sign = 2; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getHash = function() { +proto.xudp2p.SessionInitPacket.prototype.getSign = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setHash = function(value) { +proto.xudp2p.SessionInitPacket.prototype.setSign = function(value) { jspb.Message.setField(this, 2, value); }; /** - * optional string version = 3; + * optional string peer_pub_key = 3; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getVersion = function() { +proto.xudp2p.SessionInitPacket.prototype.getPeerPubKey = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setVersion = function(value) { +proto.xudp2p.SessionInitPacket.prototype.setPeerPubKey = function(value) { jspb.Message.setField(this, 3, value); }; /** - * optional string node_pub_key = 4; + * optional string ephemeral_pub_key = 4; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getNodePubKey = function() { +proto.xudp2p.SessionInitPacket.prototype.getEphemeralPubKey = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setNodePubKey = function(value) { +proto.xudp2p.SessionInitPacket.prototype.setEphemeralPubKey = function(value) { jspb.Message.setField(this, 4, value); }; /** - * repeated Address addresses = 5; - * @return {!Array.} + * optional NodeState node_state = 5; + * @return {?proto.xudp2p.NodeState} */ -proto.xudp2p.HelloPacket.prototype.getAddressesList = function() { - return /** @type{!Array.} */ ( - jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Address, 5)); +proto.xudp2p.SessionInitPacket.prototype.getNodeState = function() { + return /** @type{?proto.xudp2p.NodeState} */ ( + jspb.Message.getWrapperField(this, proto.xudp2p.NodeState, 5)); }; -/** @param {!Array.} value */ -proto.xudp2p.HelloPacket.prototype.setAddressesList = function(value) { - jspb.Message.setRepeatedWrapperField(this, 5, value); +/** @param {?proto.xudp2p.NodeState|undefined} value */ +proto.xudp2p.SessionInitPacket.prototype.setNodeState = function(value) { + jspb.Message.setWrapperField(this, 5, value); +}; + + +proto.xudp2p.SessionInitPacket.prototype.clearNodeState = function() { + this.setNodeState(undefined); }; /** - * @param {!proto.xudp2p.Address=} opt_value - * @param {number=} opt_index - * @return {!proto.xudp2p.Address} + * Returns whether this field is set. + * @return {!boolean} */ -proto.xudp2p.HelloPacket.prototype.addAddresses = function(opt_value, opt_index) { - return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.xudp2p.Address, opt_index); +proto.xudp2p.SessionInitPacket.prototype.hasNodeState = function() { + return jspb.Message.getField(this, 5) != null; }; -proto.xudp2p.HelloPacket.prototype.clearAddressesList = function() { - this.setAddressesList([]); + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.xudp2p.SessionAckPacket = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; +goog.inherits(proto.xudp2p.SessionAckPacket, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.xudp2p.SessionAckPacket.displayName = 'proto.xudp2p.SessionAckPacket'; +} +if (jspb.Message.GENERATE_TO_OBJECT) { /** - * repeated string pairs = 6; - * @return {!Array.} + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} */ -proto.xudp2p.HelloPacket.prototype.getPairsList = function() { - return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 6)); +proto.xudp2p.SessionAckPacket.prototype.toObject = function(opt_includeInstance) { + return proto.xudp2p.SessionAckPacket.toObject(opt_includeInstance, this); }; -/** @param {!Array.} value */ -proto.xudp2p.HelloPacket.prototype.setPairsList = function(value) { - jspb.Message.setField(this, 6, value || []); +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.xudp2p.SessionAckPacket} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.xudp2p.SessionAckPacket.toObject = function(includeInstance, msg) { + var f, obj = { + id: jspb.Message.getFieldWithDefault(msg, 1, ""), + reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), + ephemeralPubKey: jspb.Message.getFieldWithDefault(msg, 3, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; }; +} /** - * @param {!string} value - * @param {number=} opt_index + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.xudp2p.SessionAckPacket} */ -proto.xudp2p.HelloPacket.prototype.addPairs = function(value, opt_index) { - jspb.Message.addToRepeatedField(this, 6, value, opt_index); +proto.xudp2p.SessionAckPacket.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.xudp2p.SessionAckPacket; + return proto.xudp2p.SessionAckPacket.deserializeBinaryFromReader(msg, reader); }; -proto.xudp2p.HelloPacket.prototype.clearPairsList = function() { - this.setPairsList([]); +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.xudp2p.SessionAckPacket} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.xudp2p.SessionAckPacket} + */ +proto.xudp2p.SessionAckPacket.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setId(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setReqId(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setEphemeralPubKey(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.xudp2p.SessionAckPacket.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.xudp2p.SessionAckPacket.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.xudp2p.SessionAckPacket} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.xudp2p.SessionAckPacket.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getId(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getReqId(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getEphemeralPubKey(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } }; /** - * optional string raiden_address = 7; + * optional string id = 1; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getRaidenAddress = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, "")); +proto.xudp2p.SessionAckPacket.prototype.getId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setRaidenAddress = function(value) { - jspb.Message.setField(this, 7, value); +proto.xudp2p.SessionAckPacket.prototype.setId = function(value) { + jspb.Message.setField(this, 1, value); }; /** - * optional string lndbtc_pub_key = 8; + * optional string req_id = 2; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getLndbtcPubKey = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, "")); +proto.xudp2p.SessionAckPacket.prototype.getReqId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setLndbtcPubKey = function(value) { - jspb.Message.setField(this, 8, value); +proto.xudp2p.SessionAckPacket.prototype.setReqId = function(value) { + jspb.Message.setField(this, 2, value); }; /** - * optional string lndltc_pub_key = 9; + * optional string ephemeral_pub_key = 3; * @return {string} */ -proto.xudp2p.HelloPacket.prototype.getLndltcPubKey = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, "")); +proto.xudp2p.SessionAckPacket.prototype.getEphemeralPubKey = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ -proto.xudp2p.HelloPacket.prototype.setLndltcPubKey = function(value) { - jspb.Message.setField(this, 9, value); +proto.xudp2p.SessionAckPacket.prototype.setEphemeralPubKey = function(value) { + jspb.Message.setField(this, 3, value); }; @@ -2330,9 +2951,8 @@ proto.xudp2p.DisconnectingPacket.prototype.toObject = function(opt_includeInstan proto.xudp2p.DisconnectingPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - hash: jspb.Message.getFieldWithDefault(msg, 2, ""), - reason: jspb.Message.getFieldWithDefault(msg, 3, 0), - payload: jspb.Message.getFieldWithDefault(msg, 4, "") + reason: jspb.Message.getFieldWithDefault(msg, 2, 0), + payload: jspb.Message.getFieldWithDefault(msg, 3, "") }; if (includeInstance) { @@ -2374,14 +2994,10 @@ proto.xudp2p.DisconnectingPacket.deserializeBinaryFromReader = function(msg, rea msg.setId(value); break; case 2: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 3: var value = /** @type {number} */ (reader.readUint32()); msg.setReason(value); break; - case 4: + case 3: var value = /** @type {string} */ (reader.readString()); msg.setPayload(value); break; @@ -2421,24 +3037,17 @@ proto.xudp2p.DisconnectingPacket.serializeBinaryToWriter = function(message, wri f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 2, - f - ); - } f = message.getReason(); if (f !== 0) { writer.writeUint32( - 3, + 2, f ); } f = message.getPayload(); if (f.length > 0) { writer.writeString( - 4, + 3, f ); } @@ -2461,47 +3070,32 @@ proto.xudp2p.DisconnectingPacket.prototype.setId = function(value) { /** - * optional string hash = 2; - * @return {string} - */ -proto.xudp2p.DisconnectingPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.DisconnectingPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 2, value); -}; - - -/** - * optional uint32 reason = 3; + * optional uint32 reason = 2; * @return {number} */ proto.xudp2p.DisconnectingPacket.prototype.getReason = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); }; /** @param {number} value */ proto.xudp2p.DisconnectingPacket.prototype.setReason = function(value) { - jspb.Message.setField(this, 3, value); + jspb.Message.setField(this, 2, value); }; /** - * optional string payload = 4; + * optional string payload = 3; * @return {string} */ proto.xudp2p.DisconnectingPacket.prototype.getPayload = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ proto.xudp2p.DisconnectingPacket.prototype.setPayload = function(value) { - jspb.Message.setField(this, 4, value); + jspb.Message.setField(this, 3, value); }; @@ -2670,7 +3264,7 @@ if (goog.DEBUG && !COMPILED) { * @private {!Array} * @const */ -proto.xudp2p.NodesPacket.repeatedFields_ = [4]; +proto.xudp2p.NodesPacket.repeatedFields_ = [3]; @@ -2703,7 +3297,6 @@ proto.xudp2p.NodesPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), - hash: jspb.Message.getFieldWithDefault(msg, 3, ""), nodesList: jspb.Message.toObjectList(msg.getNodesList(), proto.xudp2p.Node.toObject, includeInstance) }; @@ -2751,10 +3344,6 @@ proto.xudp2p.NodesPacket.deserializeBinaryFromReader = function(msg, reader) { msg.setReqId(value); break; case 3: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 4: var value = new proto.xudp2p.Node; reader.readMessage(value,proto.xudp2p.Node.deserializeBinaryFromReader); msg.addNodes(value); @@ -2802,17 +3391,10 @@ proto.xudp2p.NodesPacket.serializeBinaryToWriter = function(message, writer) { f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 3, - f - ); - } f = message.getNodesList(); if (f.length > 0) { writer.writeRepeatedMessage( - 4, + 3, f, proto.xudp2p.Node.serializeBinaryToWriter ); @@ -2851,33 +3433,18 @@ proto.xudp2p.NodesPacket.prototype.setReqId = function(value) { /** - * optional string hash = 3; - * @return {string} - */ -proto.xudp2p.NodesPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.NodesPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 3, value); -}; - - -/** - * repeated Node nodes = 4; + * repeated Node nodes = 3; * @return {!Array.} */ proto.xudp2p.NodesPacket.prototype.getNodesList = function() { return /** @type{!Array.} */ ( - jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Node, 4)); + jspb.Message.getRepeatedWrapperField(this, proto.xudp2p.Node, 3)); }; /** @param {!Array.} value */ proto.xudp2p.NodesPacket.prototype.setNodesList = function(value) { - jspb.Message.setRepeatedWrapperField(this, 4, value); + jspb.Message.setRepeatedWrapperField(this, 3, value); }; @@ -2887,7 +3454,7 @@ proto.xudp2p.NodesPacket.prototype.setNodesList = function(value) { * @return {!proto.xudp2p.Node} */ proto.xudp2p.NodesPacket.prototype.addNodes = function(opt_value, opt_index) { - return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.xudp2p.Node, opt_index); + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.xudp2p.Node, opt_index); }; @@ -2944,12 +3511,11 @@ proto.xudp2p.SwapRequestPacket.prototype.toObject = function(opt_includeInstance proto.xudp2p.SwapRequestPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), - hash: jspb.Message.getFieldWithDefault(msg, 2, ""), - proposedQuantity: +jspb.Message.getFieldWithDefault(msg, 3, 0.0), - pairId: jspb.Message.getFieldWithDefault(msg, 4, ""), - orderId: jspb.Message.getFieldWithDefault(msg, 5, ""), - rHash: jspb.Message.getFieldWithDefault(msg, 6, ""), - takerCltvDelta: jspb.Message.getFieldWithDefault(msg, 7, 0) + proposedQuantity: +jspb.Message.getFieldWithDefault(msg, 2, 0.0), + pairId: jspb.Message.getFieldWithDefault(msg, 3, ""), + orderId: jspb.Message.getFieldWithDefault(msg, 4, ""), + rHash: jspb.Message.getFieldWithDefault(msg, 5, ""), + takerCltvDelta: jspb.Message.getFieldWithDefault(msg, 6, 0) }; if (includeInstance) { @@ -2991,26 +3557,22 @@ proto.xudp2p.SwapRequestPacket.deserializeBinaryFromReader = function(msg, reade msg.setId(value); break; case 2: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 3: var value = /** @type {number} */ (reader.readDouble()); msg.setProposedQuantity(value); break; - case 4: + case 3: var value = /** @type {string} */ (reader.readString()); msg.setPairId(value); break; - case 5: + case 4: var value = /** @type {string} */ (reader.readString()); msg.setOrderId(value); break; - case 6: + case 5: var value = /** @type {string} */ (reader.readString()); msg.setRHash(value); break; - case 7: + case 6: var value = /** @type {number} */ (reader.readInt32()); msg.setTakerCltvDelta(value); break; @@ -3050,45 +3612,38 @@ proto.xudp2p.SwapRequestPacket.serializeBinaryToWriter = function(message, write f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 2, - f - ); - } f = message.getProposedQuantity(); if (f !== 0.0) { writer.writeDouble( - 3, + 2, f ); } f = message.getPairId(); if (f.length > 0) { writer.writeString( - 4, + 3, f ); } f = message.getOrderId(); if (f.length > 0) { writer.writeString( - 5, + 4, f ); } f = message.getRHash(); if (f.length > 0) { writer.writeString( - 6, + 5, f ); } f = message.getTakerCltvDelta(); if (f !== 0) { writer.writeInt32( - 7, + 6, f ); } @@ -3111,92 +3666,77 @@ proto.xudp2p.SwapRequestPacket.prototype.setId = function(value) { /** - * optional string hash = 2; - * @return {string} - */ -proto.xudp2p.SwapRequestPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.SwapRequestPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 2, value); -}; - - -/** - * optional double proposed_quantity = 3; + * optional double proposed_quantity = 2; * @return {number} */ proto.xudp2p.SwapRequestPacket.prototype.getProposedQuantity = function() { - return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 3, 0.0)); + return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 2, 0.0)); }; /** @param {number} value */ proto.xudp2p.SwapRequestPacket.prototype.setProposedQuantity = function(value) { - jspb.Message.setField(this, 3, value); + jspb.Message.setField(this, 2, value); }; /** - * optional string pair_id = 4; + * optional string pair_id = 3; * @return {string} */ proto.xudp2p.SwapRequestPacket.prototype.getPairId = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ proto.xudp2p.SwapRequestPacket.prototype.setPairId = function(value) { - jspb.Message.setField(this, 4, value); + jspb.Message.setField(this, 3, value); }; /** - * optional string order_id = 5; + * optional string order_id = 4; * @return {string} */ proto.xudp2p.SwapRequestPacket.prototype.getOrderId = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); }; /** @param {string} value */ proto.xudp2p.SwapRequestPacket.prototype.setOrderId = function(value) { - jspb.Message.setField(this, 5, value); + jspb.Message.setField(this, 4, value); }; /** - * optional string r_hash = 6; + * optional string r_hash = 5; * @return {string} */ proto.xudp2p.SwapRequestPacket.prototype.getRHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); }; /** @param {string} value */ proto.xudp2p.SwapRequestPacket.prototype.setRHash = function(value) { - jspb.Message.setField(this, 6, value); + jspb.Message.setField(this, 5, value); }; /** - * optional int32 taker_cltv_delta = 7; + * optional int32 taker_cltv_delta = 6; * @return {number} */ proto.xudp2p.SwapRequestPacket.prototype.getTakerCltvDelta = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); }; /** @param {number} value */ proto.xudp2p.SwapRequestPacket.prototype.setTakerCltvDelta = function(value) { - jspb.Message.setField(this, 7, value); + jspb.Message.setField(this, 6, value); }; @@ -3249,10 +3789,9 @@ proto.xudp2p.SwapAcceptedPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), - hash: jspb.Message.getFieldWithDefault(msg, 3, ""), - rHash: jspb.Message.getFieldWithDefault(msg, 4, ""), - quantity: +jspb.Message.getFieldWithDefault(msg, 5, 0.0), - makerCltvDelta: jspb.Message.getFieldWithDefault(msg, 6, 0) + rHash: jspb.Message.getFieldWithDefault(msg, 3, ""), + quantity: +jspb.Message.getFieldWithDefault(msg, 4, 0.0), + makerCltvDelta: jspb.Message.getFieldWithDefault(msg, 5, 0) }; if (includeInstance) { @@ -3298,18 +3837,14 @@ proto.xudp2p.SwapAcceptedPacket.deserializeBinaryFromReader = function(msg, read msg.setReqId(value); break; case 3: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 4: var value = /** @type {string} */ (reader.readString()); msg.setRHash(value); break; - case 5: + case 4: var value = /** @type {number} */ (reader.readDouble()); msg.setQuantity(value); break; - case 6: + case 5: var value = /** @type {number} */ (reader.readInt32()); msg.setMakerCltvDelta(value); break; @@ -3356,31 +3891,24 @@ proto.xudp2p.SwapAcceptedPacket.serializeBinaryToWriter = function(message, writ f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 3, - f - ); - } f = message.getRHash(); if (f.length > 0) { writer.writeString( - 4, + 3, f ); } f = message.getQuantity(); if (f !== 0.0) { writer.writeDouble( - 5, + 4, f ); } f = message.getMakerCltvDelta(); if (f !== 0) { writer.writeInt32( - 6, + 5, f ); } @@ -3418,62 +3946,47 @@ proto.xudp2p.SwapAcceptedPacket.prototype.setReqId = function(value) { /** - * optional string hash = 3; - * @return {string} - */ -proto.xudp2p.SwapAcceptedPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.SwapAcceptedPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 3, value); -}; - - -/** - * optional string r_hash = 4; + * optional string r_hash = 3; * @return {string} */ proto.xudp2p.SwapAcceptedPacket.prototype.getRHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ proto.xudp2p.SwapAcceptedPacket.prototype.setRHash = function(value) { - jspb.Message.setField(this, 4, value); + jspb.Message.setField(this, 3, value); }; /** - * optional double quantity = 5; + * optional double quantity = 4; * @return {number} */ proto.xudp2p.SwapAcceptedPacket.prototype.getQuantity = function() { - return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 5, 0.0)); + return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 4, 0.0)); }; /** @param {number} value */ proto.xudp2p.SwapAcceptedPacket.prototype.setQuantity = function(value) { - jspb.Message.setField(this, 5, value); + jspb.Message.setField(this, 4, value); }; /** - * optional int32 maker_cltv_delta = 6; + * optional int32 maker_cltv_delta = 5; * @return {number} */ proto.xudp2p.SwapAcceptedPacket.prototype.getMakerCltvDelta = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); }; /** @param {number} value */ proto.xudp2p.SwapAcceptedPacket.prototype.setMakerCltvDelta = function(value) { - jspb.Message.setField(this, 6, value); + jspb.Message.setField(this, 5, value); }; @@ -3526,8 +4039,7 @@ proto.xudp2p.SwapCompletePacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), - hash: jspb.Message.getFieldWithDefault(msg, 3, ""), - rHash: jspb.Message.getFieldWithDefault(msg, 4, "") + rHash: jspb.Message.getFieldWithDefault(msg, 3, "") }; if (includeInstance) { @@ -3573,10 +4085,6 @@ proto.xudp2p.SwapCompletePacket.deserializeBinaryFromReader = function(msg, read msg.setReqId(value); break; case 3: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 4: var value = /** @type {string} */ (reader.readString()); msg.setRHash(value); break; @@ -3623,17 +4131,10 @@ proto.xudp2p.SwapCompletePacket.serializeBinaryToWriter = function(message, writ f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 3, - f - ); - } f = message.getRHash(); if (f.length > 0) { writer.writeString( - 4, + 3, f ); } @@ -3671,32 +4172,17 @@ proto.xudp2p.SwapCompletePacket.prototype.setReqId = function(value) { /** - * optional string hash = 3; - * @return {string} - */ -proto.xudp2p.SwapCompletePacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.SwapCompletePacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 3, value); -}; - - -/** - * optional string r_hash = 4; + * optional string r_hash = 3; * @return {string} */ proto.xudp2p.SwapCompletePacket.prototype.getRHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ proto.xudp2p.SwapCompletePacket.prototype.setRHash = function(value) { - jspb.Message.setField(this, 4, value); + jspb.Message.setField(this, 3, value); }; @@ -3749,10 +4235,9 @@ proto.xudp2p.SwapFailedPacket.toObject = function(includeInstance, msg) { var f, obj = { id: jspb.Message.getFieldWithDefault(msg, 1, ""), reqId: jspb.Message.getFieldWithDefault(msg, 2, ""), - hash: jspb.Message.getFieldWithDefault(msg, 3, ""), - rHash: jspb.Message.getFieldWithDefault(msg, 4, ""), - errorMessage: jspb.Message.getFieldWithDefault(msg, 5, ""), - failureReason: jspb.Message.getFieldWithDefault(msg, 6, 0) + rHash: jspb.Message.getFieldWithDefault(msg, 3, ""), + errorMessage: jspb.Message.getFieldWithDefault(msg, 4, ""), + failureReason: jspb.Message.getFieldWithDefault(msg, 5, 0) }; if (includeInstance) { @@ -3798,18 +4283,14 @@ proto.xudp2p.SwapFailedPacket.deserializeBinaryFromReader = function(msg, reader msg.setReqId(value); break; case 3: - var value = /** @type {string} */ (reader.readString()); - msg.setHash(value); - break; - case 4: var value = /** @type {string} */ (reader.readString()); msg.setRHash(value); break; - case 5: + case 4: var value = /** @type {string} */ (reader.readString()); msg.setErrorMessage(value); break; - case 6: + case 5: var value = /** @type {number} */ (reader.readUint32()); msg.setFailureReason(value); break; @@ -3856,31 +4337,24 @@ proto.xudp2p.SwapFailedPacket.serializeBinaryToWriter = function(message, writer f ); } - f = message.getHash(); - if (f.length > 0) { - writer.writeString( - 3, - f - ); - } f = message.getRHash(); if (f.length > 0) { writer.writeString( - 4, + 3, f ); } f = message.getErrorMessage(); if (f.length > 0) { writer.writeString( - 5, + 4, f ); } f = message.getFailureReason(); if (f !== 0) { writer.writeUint32( - 6, + 5, f ); } @@ -3918,62 +4392,47 @@ proto.xudp2p.SwapFailedPacket.prototype.setReqId = function(value) { /** - * optional string hash = 3; - * @return {string} - */ -proto.xudp2p.SwapFailedPacket.prototype.getHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); -}; - - -/** @param {string} value */ -proto.xudp2p.SwapFailedPacket.prototype.setHash = function(value) { - jspb.Message.setField(this, 3, value); -}; - - -/** - * optional string r_hash = 4; + * optional string r_hash = 3; * @return {string} */ proto.xudp2p.SwapFailedPacket.prototype.getRHash = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ proto.xudp2p.SwapFailedPacket.prototype.setRHash = function(value) { - jspb.Message.setField(this, 4, value); + jspb.Message.setField(this, 3, value); }; /** - * optional string error_message = 5; + * optional string error_message = 4; * @return {string} */ proto.xudp2p.SwapFailedPacket.prototype.getErrorMessage = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); }; /** @param {string} value */ proto.xudp2p.SwapFailedPacket.prototype.setErrorMessage = function(value) { - jspb.Message.setField(this, 5, value); + jspb.Message.setField(this, 4, value); }; /** - * optional uint32 failure_reason = 6; + * optional uint32 failure_reason = 5; * @return {number} */ proto.xudp2p.SwapFailedPacket.prototype.getFailureReason = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); }; /** @param {number} value */ proto.xudp2p.SwapFailedPacket.prototype.setFailureReason = function(value) { - jspb.Message.setField(this, 6, value); + jspb.Message.setField(this, 5, value); }; diff --git a/lib/proto/xudrpc.swagger.json b/lib/proto/xudrpc.swagger.json index 8ce447861..2c6729048 100644 --- a/lib/proto/xudrpc.swagger.json +++ b/lib/proto/xudrpc.swagger.json @@ -21,7 +21,7 @@ "operationId": "AddCurrency", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcAddCurrencyResponse" } @@ -48,7 +48,7 @@ "operationId": "AddPair", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcAddPairResponse" } @@ -75,7 +75,7 @@ "operationId": "Ban", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcBanResponse" } @@ -102,7 +102,7 @@ "operationId": "ChannelBalance", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcChannelBalanceResponse" } @@ -128,7 +128,7 @@ "operationId": "Connect", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcConnectResponse" } @@ -155,7 +155,7 @@ "operationId": "ListCurrencies", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcListCurrenciesResponse" } @@ -172,7 +172,7 @@ "operationId": "ExecuteSwap", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcSwapSuccess" } @@ -199,7 +199,7 @@ "operationId": "GetInfo", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcGetInfoResponse" } @@ -216,7 +216,7 @@ "operationId": "GetNodeInfo", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcGetNodeInfoResponse" } @@ -242,7 +242,7 @@ "operationId": "ListOrders", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcListOrdersResponse" } @@ -276,7 +276,7 @@ "operationId": "ListPairs", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcListPairsResponse" } @@ -293,7 +293,7 @@ "operationId": "ListPeers", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcListPeersResponse" } @@ -310,7 +310,7 @@ "operationId": "PlaceOrder", "responses": { "200": { - "description": "A successful response.(streaming responses)", + "description": "(streaming responses)", "schema": { "$ref": "#/definitions/xudrpcPlaceOrderEvent" } @@ -337,7 +337,7 @@ "operationId": "PlaceOrderSync", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcPlaceOrderResponse" } @@ -364,7 +364,7 @@ "operationId": "RemoveCurrency", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcRemoveCurrencyResponse" } @@ -391,7 +391,7 @@ "operationId": "RemoveOrder", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcRemoveOrderResponse" } @@ -418,7 +418,7 @@ "operationId": "RemovePair", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcRemovePairResponse" } @@ -445,7 +445,7 @@ "operationId": "Shutdown", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcShutdownResponse" } @@ -499,7 +499,7 @@ "operationId": "SubscribeRemovedOrders", "responses": { "200": { - "description": "A successful response.(streaming responses)", + "description": "(streaming responses)", "schema": { "$ref": "#/definitions/xudrpcOrderRemoval" } @@ -516,7 +516,7 @@ "operationId": "SubscribeSwaps", "responses": { "200": { - "description": "A successful response.(streaming responses)", + "description": "(streaming responses)", "schema": { "$ref": "#/definitions/xudrpcSwapSuccess" } @@ -543,7 +543,7 @@ "operationId": "Unban", "responses": { "200": { - "description": "A successful response.", + "description": "", "schema": { "$ref": "#/definitions/xudrpcUnbanResponse" } diff --git a/lib/service/Service.ts b/lib/service/Service.ts index adc24639f..fba9f7bd5 100644 --- a/lib/service/Service.ts +++ b/lib/service/Service.ts @@ -224,7 +224,7 @@ class Service extends EventEmitter { * Get general information about this Exchange Union node. */ public getInfo = async (): Promise => { - const { nodePubKey, addresses } = this.pool.handshakeData; + const { nodePubKey, addresses } = this.pool.nodeState; const uris: string[] = []; diff --git a/lib/types/enums.ts b/lib/types/enums.ts index 160c84fe6..18b69fa5d 100644 --- a/lib/types/enums.ts +++ b/lib/types/enums.ts @@ -21,6 +21,16 @@ export enum Network { RegTest = 'regtest', } +/** + * Magic value indicating wire msg origin network, and used to seek to next msg when stream state is unknown + */ +export enum NetworkMagic { + MainNet = 0xd9b4bef9, + TestNet = 0x0709110b, + SimNet = 0x12141c16, + RegTest = 0xdab5bffa, +} + export enum SwapRole { Taker = 0, Maker = 1, @@ -57,10 +67,8 @@ export enum ReputationEvent { PacketTimeout = 2, SwapFailure = 3, SwapSuccess = 4, - MaxParserBufferSizeExceeded = 5, - InvalidPacket = 6, - UnknownPacketType = 7, - PacketDataIntegrityError = 8, + WireProtocolErr = 5, + InvalidAuth = 6, } export enum SwapFailureReason { @@ -101,4 +109,7 @@ export enum DisconnectionReason { AlreadyConnected = 8, Shutdown = 9, MalformedVersion = 10, + AuthFailureInvalidTarget = 11, + AuthFailureInvalidSignature = 12, + WireProtocolErr = 13, } diff --git a/lib/types/p2p.ts b/lib/types/p2p.ts index f5d7fcc22..a041a57d8 100644 --- a/lib/types/p2p.ts +++ b/lib/types/p2p.ts @@ -12,7 +12,7 @@ export type NodeConnectionInfo = { lastAddress?: Address; }; -export type HandshakeState = { +export type NodeState = { version: string; nodePubKey: string; addresses?: Address[]; @@ -22,7 +22,7 @@ export type HandshakeState = { lndltcPubKey?: string; }; -export type HandshakeStateUpdate = { +export type NodeStateUpdate = { addresses?: Address[]; pairs?: string[]; raidenAddress?: string; @@ -53,7 +53,7 @@ export type PoolConfig = { addresses: string[]; }; -export function isHandshakeState(obj: any): obj is HandshakeState { +export function isNodeState(obj: any): obj is NodeState { return obj && typeof obj.version === 'string' && typeof obj.nodePubKey === 'string' && Array.isArray(obj.addresses) && Array.isArray(obj.pairs); } diff --git a/package.json b/package.json index f1b011333..1bc72b723 100644 --- a/package.json +++ b/package.json @@ -23,13 +23,14 @@ "proto:p2p": "cross-os proto:p2p", "start": "node dist/Xud.js", "stop": "cross-os stop", - "test": "npm run test:unit && npm run test:int && npm run test:p2p", + "test": "npm run test:unit && npm run test:crypto && npm run test:int && npm run test:p2p", "test:int": "mocha -r ts-node/register test/integration/*", "test:int:watch": "mocha -r ts-node/register test/integration/* --watch --watch-extensions ts", "test:unit": "mocha -r ts-node/register test/unit/*", "test:unit:watch": "mocha -r ts-node/register test/unit/* --watch --watch-extensions ts", "test:p2p": "mocha -r ts-node/register test/p2p/*", "test:p2p:watch": "mocha -r ts-node/register test/p2p/* --watch --watch-extensions ts", + "test:crypto": "mocha -r ts-node/register test/crypto/*", "typedoc": "typedoc --out typedoc --module commonjs --target es6 lib --readme none", "preversion": "npm run lintNoFix && npm test && npm run compile", "version": "npm run config && npm run changelog && git add sample-xud.conf CHANGELOG.md && npm run typedoc" @@ -56,8 +57,8 @@ "win32": "node_modules\\grpc-tools\\bin\\protoc --js_out=\"import_style=commonjs,binary:lib\\proto\" --ts_out=\"lib\\proto\" --grpc_out=\"lib\\proto\" --plugin=\"protoc-gen-grpc=node_modules\\.bin\\grpc_tools_node_protoc_plugin.cmd\" --plugin=\"protoc-gen-ts=node_modules\\.bin\\protoc-gen-ts.cmd\" -I=\"proto\" proto\\xudrpc.proto proto\\hash_resolver.proto proto\\lndrpc.proto proto\\annotations.proto proto\\google\\api\\http.proto proto\\google\\protobuf\\descriptor.proto" }, "proto:p2p": { - "linux": "./node_modules/grpc-tools/bin/protoc --js_out='import_style=commonjs,binary:lib/proto' --ts_out='lib/proto' --grpc_out='lib/proto' --plugin='protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin' --plugin='protoc-gen-ts=node_modules/grpc_tools_node_protoc_ts/bin/protoc-gen-ts' -I='proto' proto/xudp2p.proto", - "darwin": "./node_modules/grpc-tools/bin/protoc --js_out='import_style=commonjs,binary:lib/proto' --ts_out='lib/proto' --grpc_out='lib/proto' --plugin='protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin' --plugin='protoc-gen-ts=node_modules/grpc_tools_node_protoc_ts/bin/protoc-gen-ts' -I='proto' proto/xudp2p.proto", + "linux": "./node_modules/grpc-tools/bin/protoc --js_out='import_style=commonjs,binary:lib/proto' --ts_out='lib/proto' --grpc_out='lib/proto' --plugin='protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin' --plugin='protoc-gen-ts=node_modules/.bin/protoc-gen-ts' -I='proto' proto/xudp2p.proto", + "darwin": "./node_modules/grpc-tools/bin/protoc --js_out='import_style=commonjs,binary:lib/proto' --ts_out='lib/proto' --grpc_out='lib/proto' --plugin='protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin' --plugin='protoc-gen-ts=node_modules/.bin/protoc-gen-ts' -I='proto' proto/xudp2p.proto", "win32": "node_modules\\grpc-tools\\bin\\protoc --js_out=\"import_style=commonjs,binary:lib\\proto\" --ts_out=\"lib\\proto\" --grpc_out=\"lib\\proto\" --plugin=\"protoc-gen-grpc=node_modules\\.bin\\grpc_tools_node_protoc_plugin.cmd\" --plugin=\"protoc-gen-ts=node_modules\\.bin\\protoc-gen-ts.cmd\" -I=\"proto\" proto\\xudp2p.proto" }, "swagger": { diff --git a/proto/xudp2p.proto b/proto/xudp2p.proto index 15fcfbc1b..09d4f0485 100644 --- a/proto/xudp2p.proto +++ b/proto/xudp2p.proto @@ -3,120 +3,131 @@ syntax = "proto3"; package xudp2p; message Address { - string host = 1 [json_name = "host"]; - uint32 port = 2 [json_name = "port"]; + string host = 1; + uint32 port = 2; } message Order { - string id = 1 [json_name = "id"]; - string pair_id = 2 [json_name = "pair_id"]; - double price = 3 [json_name = "price"]; - double quantity = 4 [json_name = "quantity"]; - bool is_buy = 5 [json_name = "is_buy"]; + string id = 1; + string pair_id = 2; + double price = 3; + double quantity = 4; + bool is_buy = 5; } message Node { - string node_pub_key = 1 [json_name = "node_pub_key"]; - repeated Address addresses = 2 [json_name = "addresses"]; + string node_pub_key = 1; + repeated Address addresses = 2; +} + +message NodeState { + string version = 1; + string node_pub_key = 2; + repeated Address addresses = 3; + repeated string pairs = 4; + string raiden_address = 5; + string lnd_btc_pub_key = 6; + string lnd_ltc_pub_key = 7; } message PingPacket { - string id = 1 [json_name = "id"]; + string id = 1; } message PongPacket { - string id = 1 [json_name = "id"]; - string req_id = 2 [json_name = "req_id"]; + string id = 1; + string req_id = 2; } message OrderPacket { - string id = 1 [json_name = "id"]; - string hash = 2 [json_name = "hash"]; - Order order = 3 [json_name = "order"]; + string id = 1; + Order order = 2; } message OrderInvalidationPacket { - string id = 1 [json_name = "id"]; - string hash = 2 [json_name = "hash"]; - string order_id = 3 [json_name = "order_id"]; - string pair_id = 4 [json_name = "pair_id"]; - double quantity = 5 [json_name = "quantity"]; + string id = 1; + string order_id = 2; + string pair_id = 3; + double quantity = 4; } message GetOrdersPacket { - string id = 1 [json_name = "id"]; - string hash = 2 [json_name = "hash"]; - repeated string pair_ids = 3 [json_name = "pair_ids"]; + string id = 1; + repeated string pair_ids = 2; } message OrdersPacket { - string id = 1 [json_name = "id"]; - string req_id = 2 [json_name = "req_id"]; - string hash = 3 [json_name = "hash"]; - repeated Order orders = 4 [json_name = "orders"]; + string id = 1; + string req_id = 2; + repeated Order orders = 3; +} + +message NodeStateUpdatePacket { + string id = 1; + repeated Address addresses = 2; + repeated string pairs = 3; + string raiden_address = 4; + string lnd_btc_pub_key = 5; + string lnd_ltc_pub_key = 6; +} + +message SessionInitPacket { + string id = 1; + string sign = 2; + string peer_pub_key = 3; + string ephemeral_pub_key = 4; + NodeState node_state = 5; } -message HelloPacket { - string id = 1 [json_name = "id"]; - string hash = 2 [json_name = "hash"]; - string version = 3 [json_name = "version"]; - string node_pub_key = 4 [json_name = "node_pub_key"]; - repeated Address addresses = 5 [json_name = "addresses"]; - repeated string pairs = 6 [json_name = "pairs"]; - string raiden_address = 7 [json_name = "raiden_address"]; - string lndbtc_pub_key = 8 [json_name = "lnd_btc_pub_key"]; - string lndltc_pub_key = 9 [json_name = "lnd_ltc_pub_key"]; +message SessionAckPacket { + string id = 1; + string req_id = 2; + string ephemeral_pub_key = 3; } message DisconnectingPacket { - string id = 1 [json_name = "id"]; - string hash = 2 [json_name = "hash"]; - uint32 reason = 3 [json_name = "reason"]; - string payload = 4 [json_name = "payload"]; + string id = 1; + uint32 reason = 2; + string payload = 3; } message GetNodesPacket { - string id = 1 [json_name = "id"]; + string id = 1; } message NodesPacket { - string id = 1 [json_name = "id"]; - string req_id = 2 [json_name = "req_id"]; - string hash = 3 [json_name = "hash"]; - repeated Node nodes = 4 [json_name = "nodes"]; + string id = 1; + string req_id = 2; + repeated Node nodes = 3; } message SwapRequestPacket { - string id = 1 [json_name = "id"]; - string hash = 2 [json_name = "hash"]; - double proposed_quantity = 3 [json_name = "proposed_quantity"]; - string pair_id = 4 [json_name = "pair_id"]; - string order_id = 5 [json_name = "order_id"]; - string r_hash = 6 [json_name = "r_hash"]; - int32 taker_cltv_delta = 7 [json_name = "taker_cltv_delta"]; + string id = 1; + double proposed_quantity = 2; + string pair_id = 3; + string order_id = 4; + string r_hash = 5; + int32 taker_cltv_delta = 6; } message SwapAcceptedPacket { - string id = 1 [json_name = "id"]; - string req_id = 2 [json_name = "req_id"]; - string hash = 3 [json_name = "hash"]; - string r_hash = 4 [json_name = "r_hash"]; - double quantity = 5 [json_name = "quantity"]; - int32 maker_cltv_delta = 6 [json_name = "maker_cltv_delta"]; + string id = 1; + string req_id = 2; + string r_hash = 3; + double quantity = 4; + int32 maker_cltv_delta = 5; } message SwapCompletePacket { - string id = 1 [json_name = "id"]; - string req_id = 2 [json_name = "req_id"]; - string hash = 3 [json_name = "hash"]; - string r_hash = 4 [json_name = "r_hash"]; + string id = 1; + string req_id = 2; + string r_hash = 3; } message SwapFailedPacket { - string id = 1 [json_name = "id"]; - string req_id = 2 [json_name = "req_id"]; - string hash = 3 [json_name = "hash"]; - string r_hash = 4 [json_name = "r_hash"]; - string error_message = 5 [json_name = "error_message"]; - uint32 failure_reason = 6[json_name = "failure_reason"]; + string id = 1; + string req_id = 2; + string r_hash = 3; + string error_message = 4; + uint32 failure_reason = 5; } diff --git a/test/crypto/handshake.ts b/test/crypto/handshake.ts new file mode 100644 index 000000000..812555cd4 --- /dev/null +++ b/test/crypto/handshake.ts @@ -0,0 +1,69 @@ +import crypto from 'crypto'; +import CryptoJS from 'crypto-js'; +import secp256k1 from 'secp256k1'; +import NodeKey from '../../lib/nodekey/NodeKey'; +import { expect } from 'chai'; + +describe('key exchange and symmetric encryption', () => { + let secretKey: Buffer; + + it('alice and bob should successfully exchange shared secret key', async () => { + const alice = crypto.createECDH('secp256k1'); + const bob = crypto.createECDH('secp256k1'); + + // alice and bob create an ephemeral key pair for the key exchange + const aliceEphemeralPubKey = alice.generateKeys(); + const bobEphemeralPubKey = bob.generateKeys(); + + // they exchange their ephemeral public keys + const aliceSecretKey = alice.computeSecret(bobEphemeralPubKey); + const bobSecretKey = bob.computeSecret(aliceEphemeralPubKey); + + // both alice and bob should derive the same secret key + expect(Buffer.compare(aliceSecretKey, bobSecretKey)).to.equal(0); + + secretKey = aliceSecretKey; + }); + + it('alice should encrypt messages that bob can decrypt', async () => { + const msg = crypto.randomBytes(100); + + const iv = crypto.randomBytes(16); + const cipher = crypto.createCipheriv('aes-256-cbc', secretKey, iv); + const encrypted = Buffer.concat([iv, cipher.update(msg), cipher.final()]); + + const decipher = crypto.createDecipheriv('aes-256-cbc', secretKey, encrypted.slice(0, 16)); + const decrypted = Buffer.concat([decipher.update(encrypted.slice(16)), decipher.final()]); + + expect(msg.toString('hex')).to.be.equal(decrypted.toString('hex')); + }); +}); + +describe('authentication', () => { + it('alice should sign its session init data and bob should be able to verify it', async () => { + const aliceNodeKey = await NodeKey['generate'](); + const aliceNodePubKey = aliceNodeKey.nodePubKey; + const aliceNodePrivKey = aliceNodeKey['privKey']; + + const alice = crypto.createECDH('secp256k1'); + const aliceEphemeralPubKey = alice.generateKeys(); + + const msg = { + nodePubKey: aliceNodePubKey, + ephemeralPubKey: aliceEphemeralPubKey, + }; + + const msgHash = crypto + .createHash('sha256') + .update(JSON.stringify(msg)) + .digest(); + + // alice signs the hash of its handshake request data and send it to bob + const { signature } = secp256k1.sign(msgHash, aliceNodePrivKey); + + // bob verifies the signature on the handshake request data hash using alice's public key + const verified = secp256k1.verify(msgHash, signature, Buffer.from(msg.nodePubKey, 'hex')); + + expect(verified).to.be.true; + }); +}); diff --git a/test/integration/Pool.spec.ts b/test/integration/Pool.spec.ts index ab86abecd..8195d889b 100644 --- a/test/integration/Pool.spec.ts +++ b/test/integration/Pool.spec.ts @@ -1,5 +1,6 @@ import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; +import sinon from 'sinon'; import Pool from '../../lib/p2p/Pool'; import Logger, { Level } from '../../lib/Logger'; import DB from '../../lib/db/DB'; @@ -8,22 +9,20 @@ import NodeKey from '../../lib/nodekey/NodeKey'; import Peer from '../../lib/p2p/Peer'; import { Address } from '../../lib/types/p2p'; import { DisconnectionReason } from '../../lib/types/enums'; -import { HelloPacket } from '../../lib/p2p/packets/types'; -import sinon from 'sinon'; chai.use(chaiAsPromised); describe('P2P Pool Tests', async () => { let db: DB; let pool: Pool; - let nodePubKeyOne: string; + let nodeKeyOne: NodeKey; const loggers = Logger.createLoggers(Level.Warn); const sandbox = sinon.createSandbox(); const createPeer = (nodePubKey: string, addresses: Address[]) => { const peer = sandbox.createStubInstance(Peer) as any; peer.address = addresses[0]; - peer.handshakeState = { + peer.nodeState = { addresses, nodePubKey, version: 'test', @@ -41,7 +40,7 @@ describe('P2P Pool Tests', async () => { }; before(async () => { - nodePubKeyOne = (await NodeKey['generate']()).nodePubKey; + nodeKeyOne = await NodeKey['generate'](); const config = new Config(); config.p2p.listen = false; @@ -55,26 +54,26 @@ describe('P2P Pool Tests', async () => { nodePubKey: 'test', version: 'test', pairs: [], - }); + }, nodeKeyOne); }); it('should handle an opened peer', async () => { const currentNodeCount = pool['nodes'].count; const addresses = [{ host: '123.123.123.123', port: 8885 }]; - const peer = createPeer(nodePubKeyOne, addresses); + const peer = createPeer(nodeKeyOne.nodePubKey, addresses); const handleOpenPromise = pool['handleOpen'](peer); expect(handleOpenPromise).to.be.fulfilled; await handleOpenPromise; expect(pool['nodes'].count).to.equal(currentNodeCount + 1); - expect(pool['nodes'].has(nodePubKeyOne)).to.be.true; + expect(pool['nodes'].has(nodeKeyOne.nodePubKey)).to.be.true; - expect(pool['peers'].has(nodePubKeyOne)).to.be.true; + expect(pool['peers'].has(nodeKeyOne.nodePubKey)).to.be.true; const nodeInstance = await db.models.Node.find({ where: { - nodePubKey: nodePubKeyOne, + nodePubKey: nodeKeyOne.nodePubKey, }, }); expect(nodeInstance).to.not.be.undefined; @@ -83,43 +82,43 @@ describe('P2P Pool Tests', async () => { }); it('should close a peer', () => { - pool.closePeer(nodePubKeyOne, DisconnectionReason.NotAcceptingConnections); - expect(pool['peers'].has(nodePubKeyOne)).to.be.false; + pool.closePeer(nodeKeyOne.nodePubKey, DisconnectionReason.NotAcceptingConnections); + expect(pool['peers'].has(nodeKeyOne.nodePubKey)).to.be.false; expect(pool['peers'].size).to.equal(0); }); it('should ban a peer', async () => { - const banPromise = pool.banNode(nodePubKeyOne); + const banPromise = pool.banNode(nodeKeyOne.nodePubKey); expect(banPromise).to.be.fulfilled; await banPromise; - const nodeReputationPromise = await pool.getNodeReputation(nodePubKeyOne); + const nodeReputationPromise = await pool.getNodeReputation(nodeKeyOne.nodePubKey); expect(nodeReputationPromise.banned).to.be.true; }); it('should unban a peer', async () => { - const unbanPromise = pool.unbanNode(nodePubKeyOne, false); + const unbanPromise = pool.unbanNode(nodeKeyOne.nodePubKey, false); expect(unbanPromise).to.be.fulfilled; await unbanPromise; - const nodeReputationPromise = await pool.getNodeReputation(nodePubKeyOne); + const nodeReputationPromise = await pool.getNodeReputation(nodeKeyOne.nodePubKey); expect(nodeReputationPromise.banned).to.be.false; }); it('should update a node on new handshake', async () => { const addresses = [{ host: '86.75.30.9', port: 8885 }]; - const peer = createPeer(nodePubKeyOne, addresses); + const peer = createPeer(nodeKeyOne.nodePubKey, addresses); pool['handleOpen'](peer); const nodeInstance = await db.models.Node.find({ where: { - nodePubKey: nodePubKeyOne, + nodePubKey: nodeKeyOne.nodePubKey, }, }); expect(nodeInstance).to.not.be.undefined; expect(nodeInstance!.addresses!).to.have.length(1); expect(nodeInstance!.addresses![0].host).to.equal(addresses[0].host); - pool.closePeer(nodePubKeyOne, DisconnectionReason.NotAcceptingConnections); + pool.closePeer(nodeKeyOne.nodePubKey, DisconnectionReason.NotAcceptingConnections); }); after(async () => { diff --git a/test/p2p/sanity.spec.ts b/test/p2p/sanity.spec.ts index add06fe8d..774769330 100644 --- a/test/p2p/sanity.spec.ts +++ b/test/p2p/sanity.spec.ts @@ -3,7 +3,8 @@ import Xud from '../../lib/Xud'; import chaiAsPromised from 'chai-as-promised'; import { toUri } from '../../lib/utils/uriUtils'; import { getUnusedPort } from '../utils'; -import { DisconnectionReason } from '../../lib/types/enums'; +import { DisconnectionReason, ReputationEvent } from '../../lib/types/enums'; +import NodeKey from '../../lib/nodekey/NodeKey'; chai.use(chaiAsPromised); @@ -80,12 +81,23 @@ describe('P2P Sanity Tests', () => { }); it('should fail when connecting to an unexpected node pub key', async () => { + const randomPubKey = (await NodeKey['generate']()).nodePubKey; const connectPromise = nodeOne.service.connect({ - nodeUri: toUri({ nodePubKey: 'thewrongpubkey', host: 'localhost', port: nodeTwoPort }), + nodeUri: toUri({ nodePubKey: randomPubKey, host: 'localhost', port: nodeTwoPort }), retryConnecting: false, }); - await expect(connectPromise).to.be.rejectedWith( - `node at localhost:${nodeTwoPort} sent pub key ${nodeTwo.nodePubKey}, expected thewrongpubkey`); + await expect(connectPromise).to.be.rejectedWith(`Peer disconnected from us due to AuthFailureInvalidTarget`); + const listPeersResult = await nodeOne.service.listPeers(); + expect(listPeersResult).to.be.empty; + }); + + it('should fail when connecting to an invalid node pub key', async () => { + const invalidPubKey = '0123456789'; + const connectPromise = nodeOne.service.connect({ + nodeUri: toUri({ nodePubKey: invalidPubKey, host: 'localhost', port: nodeTwoPort }), + retryConnecting: false, + }); + await expect(connectPromise).to.be.rejectedWith(`Peer disconnected from us due to AuthFailureInvalidTarget`); const listPeersResult = await nodeOne.service.listPeers(); expect(listPeersResult).to.be.empty; }); diff --git a/test/unit/Parser.spec.ts b/test/unit/Parser.spec.ts index b7cd338e9..f1d49d8af 100644 --- a/test/unit/Parser.spec.ts +++ b/test/unit/Parser.spec.ts @@ -1,22 +1,30 @@ import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import Parser, { ParserErrorType } from '../../lib/p2p/Parser'; +import crypto from 'crypto'; +import Parser from '../../lib/p2p/Parser'; import { Packet, PacketType } from '../../lib/p2p/packets'; import * as packets from '../../lib/p2p/packets/types'; import { removeUndefinedProps } from '../../lib/utils/utils'; -import { DisconnectionReason, SwapFailureReason } from '../../lib/types/enums'; +import { DisconnectionReason, NetworkMagic, SwapFailureReason } from '../../lib/types/enums'; import uuid = require('uuid'); -import { Address } from '../../lib/types/p2p'; -import stringify from 'json-stable-stringify'; +import { Address, NodeState } from '../../lib/types/p2p'; +import { SessionInitPacketBody } from '../../lib/p2p/packets/types/SessionInitPacket'; +import Network from '../../lib/p2p/Network'; +import Framer from '../../lib/p2p/Framer'; +import { errorCodes } from '../../lib/p2p/errors'; +import stringify = require('json-stable-stringify'); chai.use(chaiAsPromised); describe('Parser', () => { const timeoutError = 'timeout'; + const network = new Network(NetworkMagic.TestNet); + const framer = new Framer(network); + const encryptionKey = crypto.randomBytes(Framer.ENCRYPTION_KEY_LENGTH); let parser: Parser; beforeEach(() => { - parser = new Parser(); + parser = new Parser(framer); }); function wait(num = 1): Promise { @@ -38,7 +46,7 @@ describe('Parser', () => { wait(packets.length) .then((parsedPackets) => { for (let i = 0; i < packets.length; i += 1) { - expect(packets[i]).to.deep.equal(parsedPackets[i]); + expect(stringify(packets[i])).to.equal(stringify(parsedPackets[i])); expect(packets[i].type).to.equal(parsedPackets[i].type); } resolve(); @@ -53,8 +61,19 @@ describe('Parser', () => { .then(done) .catch(done); - const raw = packet.toRaw(); - parser.feed(raw); + const data = framer.frame(packet); + parser.feed(data); + }); + + it(`should parse an encrypted valid ${PacketType[packet.type]} packet`, (done) => { + verify([packet]) + .then(done) + .catch(done); + + parser.setEncryptionKey(encryptionKey); + + const data = framer.frame(packet, encryptionKey); + parser.feed(data); }); } @@ -64,8 +83,8 @@ describe('Parser', () => { .then(() => done('err: packet is valid')) .catch(() => done()); - const raw = packet.toRaw(); - parser.feed(raw); + const data = framer.frame(packet); + parser.feed(data); }); } @@ -75,10 +94,23 @@ describe('Parser', () => { .then(done) .catch(done); - const buffer = packet.toRaw(); - const middleIndex = buffer.length >> 1; - parser.feed(buffer.slice(0, middleIndex)); - parser.feed(buffer.slice(middleIndex)); + const data = framer.frame(packet); + const middleIndex = data.length >> 1; + parser.feed(data.slice(0, middleIndex)); + parser.feed(data.slice(middleIndex)); + }); + + it(`should parse encrypted ${PacketType[packet.type]} packet split`, (done) => { + verify([packet]) + .then(done) + .catch(done); + + parser.setEncryptionKey(encryptionKey); + + const data = framer.frame(packet, encryptionKey); + const middleIndex = data.length >> 1; + parser.feed(data.slice(0, middleIndex)); + parser.feed(data.slice(middleIndex)); }); } @@ -88,7 +120,21 @@ describe('Parser', () => { .then(done) .catch(done); - parser.feed(Buffer.concat(packets.map(packet => packet.toRaw()))); + parser.feed(Buffer.concat(packets.map((packet) => { + return framer.frame(packet); + }))); + }); + + it(`should parse encrypted ${packets.map(packet => PacketType[packet.type]).join(' ')} concatenated`, (done) => { + verify(packets) + .then(done) + .catch(done); + + parser.setEncryptionKey(encryptionKey); + + parser.feed(Buffer.concat(packets.map((packet) => { + return framer.frame(packet, encryptionKey); + }))); }); } @@ -101,7 +147,24 @@ describe('Parser', () => { let remaining = Buffer.alloc(0); packets.forEach((packet) => { - const buffer = Buffer.concat([remaining, packet.toRaw()]); + const buffer = Buffer.concat([remaining, framer.frame(packet)]); + const chunk = buffer.slice(0, splitByte); // split on a specific byte + remaining = buffer.slice(splitByte); // keep the remaining for the next chunk + parser.feed(chunk); + }); + parser.feed(remaining); + }); + + it(`should parse encrypted ${packetsStr} concatenated and split on byte ${splitByte} from each packet beginning`, (done) => { + verify(packets) + .then(done) + .catch(done); + + parser.setEncryptionKey(encryptionKey); + + let remaining = Buffer.alloc(0); + packets.forEach((packet) => { + const buffer = Buffer.concat([remaining, framer.frame(packet, encryptionKey)]); const chunk = buffer.slice(0, splitByte); // split on a specific byte remaining = buffer.slice(splitByte); // keep the remaining for the next chunk parser.feed(chunk); @@ -110,7 +173,7 @@ describe('Parser', () => { }); } - const helloPacketBody = { + const nodeState: NodeState = { version: '1.0.0', nodePubKey: uuid(), addresses: [{ host: '1.1.1.1', port: 8885 }, { host: '2.2.2.2', port: 8885 }], @@ -120,23 +183,50 @@ describe('Parser', () => { lndltcPubKey: uuid(), }; + const sessionInitPacketBody: SessionInitPacketBody = { + nodeState, + sign: uuid(), + peerPubKey: uuid(), + ephemeralPubKey: uuid(), + }; + describe('test packets validation', () => { + /* tslint:disable max-line-length */ + testValidPacket(new packets.PingPacket()); testInvalidPacket(new packets.PingPacket(undefined, uuid())); testValidPacket(new packets.PongPacket(undefined, uuid())); testInvalidPacket(new packets.PongPacket(undefined)); - testValidPacket(new packets.HelloPacket(helloPacketBody)); - testValidPacket(new packets.HelloPacket({ ...helloPacketBody, pairs: [] })); - testValidPacket(new packets.HelloPacket({ ...helloPacketBody, addresses: [] })); - testValidPacket(new packets.HelloPacket(removeUndefinedProps({ ...helloPacketBody, raidenAddress: undefined }))); - testValidPacket(new packets.HelloPacket(removeUndefinedProps({ ...helloPacketBody, lndbtcPubKey: undefined }))); - testValidPacket(new packets.HelloPacket(removeUndefinedProps({ ...helloPacketBody, lndltcPubKey: undefined }))); - testInvalidPacket(new packets.HelloPacket(helloPacketBody, uuid())); - testInvalidPacket(new packets.HelloPacket(removeUndefinedProps({ ...helloPacketBody, version: undefined }))); - testInvalidPacket(new packets.HelloPacket(removeUndefinedProps({ ...helloPacketBody, nodePubKey: undefined }))); - testInvalidPacket(new packets.HelloPacket({ ...helloPacketBody, addresses: [{} as Address] })); + testValidPacket(new packets.SessionInitPacket(sessionInitPacketBody)); + testValidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: { ...nodeState, pairs: [] } })); + testValidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: { ...nodeState, addresses: [] } })); + testValidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: removeUndefinedProps({ ...nodeState, raidenAddress: undefined }) })); + testValidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: removeUndefinedProps({ ...nodeState, lndbtcPubKey: undefined }) })); + testValidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: removeUndefinedProps({ ...nodeState, lndltcPubKey: undefined }) })); + testInvalidPacket(new packets.SessionInitPacket(sessionInitPacketBody, uuid())); + testInvalidPacket(new packets.SessionInitPacket(removeUndefinedProps({ ...sessionInitPacketBody, sign: undefined }))); + testInvalidPacket(new packets.SessionInitPacket(removeUndefinedProps({ ...sessionInitPacketBody, ephemeralPubKey: undefined }))); + testInvalidPacket(new packets.SessionInitPacket(removeUndefinedProps({ ...sessionInitPacketBody, peerPubKey: undefined }))); + testInvalidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: removeUndefinedProps({ ...nodeState, nodePubKey: undefined }) })); + testInvalidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: removeUndefinedProps({ ...nodeState, version: undefined }) })); + testInvalidPacket(new packets.SessionInitPacket({ ...sessionInitPacketBody, nodeState: { ...nodeState, addresses: [{} as Address] } })); + + const sessionAckPacketBody = { ephemeralPubKey: sessionInitPacketBody.ephemeralPubKey }; + testValidPacket(new packets.SessionAckPacket(sessionAckPacketBody, uuid())); + testInvalidPacket(new packets.SessionAckPacket(sessionAckPacketBody)); + testInvalidPacket(new packets.SessionAckPacket(removeUndefinedProps({ ...sessionAckPacketBody, ephemeralPubKey: undefined }), uuid())); + + const { version, nodePubKey, ...nodeStateUpdate } = nodeState; + testValidPacket(new packets.NodeStateUpdatePacket(nodeStateUpdate)); + testValidPacket(new packets.NodeStateUpdatePacket({ ...nodeStateUpdate, pairs: [] })); + testValidPacket(new packets.NodeStateUpdatePacket({ ...nodeStateUpdate, addresses: [] })); + testValidPacket(new packets.NodeStateUpdatePacket(removeUndefinedProps({ ...nodeStateUpdate, raidenAddress: undefined }))); + testValidPacket(new packets.NodeStateUpdatePacket(removeUndefinedProps({ ...nodeStateUpdate, lndbtcPubKey: undefined }))); + testValidPacket(new packets.NodeStateUpdatePacket(removeUndefinedProps({ ...nodeStateUpdate, lndltcPubKey: undefined }))); + testInvalidPacket(new packets.NodeStateUpdatePacket(nodeStateUpdate, uuid())); + testInvalidPacket(new packets.NodeStateUpdatePacket({ ...nodeStateUpdate, addresses: [{} as Address] })); const disconnectingPacketBody = { reason: DisconnectionReason.IncompatibleProtocolVersion, @@ -253,14 +343,14 @@ describe('Parser', () => { }); describe('test TCP segmentation/concatenation support', () => { const pingPacket = new packets.PingPacket(); - const helloPacket = new packets.HelloPacket(helloPacketBody); + const sessionInitPacket = new packets.SessionInitPacket(sessionInitPacketBody); testSplitPacket(pingPacket); - testSplitPacket(helloPacket); - testConcatenatedPackets([pingPacket, helloPacket, pingPacket]); - testConcatenatedAndSplit([pingPacket, helloPacket, pingPacket], Parser.PACKET_METADATA_SIZE - 1); - testConcatenatedAndSplit([pingPacket, helloPacket, pingPacket], Parser.PACKET_METADATA_SIZE); - testConcatenatedAndSplit([pingPacket, helloPacket, pingPacket], Parser.PACKET_METADATA_SIZE + 1); + testSplitPacket(sessionInitPacket); + testConcatenatedPackets([pingPacket, sessionInitPacket, pingPacket]); + testConcatenatedAndSplit([pingPacket, sessionInitPacket, pingPacket], Framer.MSG_HEADER_LENGTH - 1); + testConcatenatedAndSplit([pingPacket, sessionInitPacket, pingPacket], Framer.MSG_HEADER_LENGTH); + testConcatenatedAndSplit([pingPacket, sessionInitPacket, pingPacket], Framer.MSG_HEADER_LENGTH + 1); }); describe('test more edge-cases', () => { @@ -269,34 +359,46 @@ describe('Parser', () => { parser.feed(Buffer.alloc(0)); }); - it(`should try parse just the metadata as a packet`, (done) => { + it(`should not try parse just the header as a packet`, (done) => { wait() .then(() => done('err: packet should not be parsed')) .catch((err) => { - if (err && err.type === ParserErrorType.InvalidPacket) { + if (err === timeoutError) { done(); } else { done(err); } }); - parser.feed(Buffer.alloc(Parser.PACKET_METADATA_SIZE)); + const sessionInitPacket = new packets.SessionInitPacket(sessionInitPacketBody); + const data = framer.frame(sessionInitPacket); + const header = data.slice(0, Framer.MSG_HEADER_LENGTH); + parser.feed(header); }); - it(`should buffer a max buffer length`, async () => { - parser = new Parser(Parser.PACKET_METADATA_SIZE, 10); + it(`should buffer a max buffer length`, (done) => { + parser = new Parser(framer, Framer.MSG_HEADER_LENGTH, 10); + + wait() + .then(() => done('err: packet should not be parsed')) + .catch((err) => { + if (err === timeoutError) { + done(); + } else { + done(err); + } + }); - await expect(wait()).to.be.rejectedWith(timeoutError); parser.feed(Buffer.allocUnsafe(10)); }); it(`should not buffer when max buffer size exceeds`, (done) => { - parser = new Parser(Parser.PACKET_METADATA_SIZE, 10); + parser = new Parser(framer, Framer.MSG_HEADER_LENGTH, 10); wait() .then(() => done('err: packet should not be parsed')) .catch((err) => { - if (err && err.type === ParserErrorType.MaxBufferSizeExceeded) { + if (err && err.code === errorCodes.PARSER_MAX_BUFFER_SIZE_EXCEEDED) { done(); } else { done(err); @@ -305,6 +407,5 @@ describe('Parser', () => { parser.feed(Buffer.allocUnsafe(11)); }); - }); });