diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 42a5ff62..e60f1fd6 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -270,7 +270,7 @@ Block._fromCompact = function _fromCompact(json) { raw = new Buffer(json.block, 'hex'); - parser = new bcoin.protocol.parser(); + parser = bcoin.protocol.parser; data = parser.parseBlock(raw); @@ -295,7 +295,7 @@ Block.prototype.toRaw = function toRaw(enc) { }; Block._fromRaw = function _fromRaw(data, enc, type) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/blockdb.js b/lib/bcoin/blockdb.js index ddb0d892..107e2d45 100644 --- a/lib/bcoin/blockdb.js +++ b/lib/bcoin/blockdb.js @@ -39,7 +39,7 @@ function BlockDB(options) { this.options = options; - this.parser = new bcoin.protocol.parser(); + this.parser = bcoin.protocol.parser; this.data = new BlockData(options); diff --git a/lib/bcoin/coin.js b/lib/bcoin/coin.js index e5064980..3b87b7a8 100644 --- a/lib/bcoin/coin.js +++ b/lib/bcoin/coin.js @@ -170,7 +170,7 @@ Coin.prototype.toRaw = function toRaw(enc) { }; Coin._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/compactblock.js b/lib/bcoin/compactblock.js index bb2c2dc0..d7f45c81 100644 --- a/lib/bcoin/compactblock.js +++ b/lib/bcoin/compactblock.js @@ -38,9 +38,16 @@ CompactBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() { }; CompactBlock.prototype.toBlock = function toBlock(peer) { - var block = peer.parser.parseBlock(this._raw); - if (!block) + var block; + + // XXX Hack + try { + block = bcoin.protocol.parser.parseBlock(this._raw); + } catch (e) { + peer.parser.emit('error', e); return; + } + return new bcoin.block(block); }; diff --git a/lib/bcoin/headers.js b/lib/bcoin/headers.js index 744e9ebf..3d0a44ae 100644 --- a/lib/bcoin/headers.js +++ b/lib/bcoin/headers.js @@ -67,7 +67,7 @@ Headers.prototype.toRaw = function toRaw(enc) { }; Headers._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index 6fbb35c2..60ecfe8b 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -396,7 +396,7 @@ Input.prototype.toRaw = function toRaw(enc) { }; Input._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/merkleblock.js b/lib/bcoin/merkleblock.js index 2370bedd..cfade6d1 100644 --- a/lib/bcoin/merkleblock.js +++ b/lib/bcoin/merkleblock.js @@ -146,7 +146,7 @@ MerkleBlock.prototype.toRaw = function toRaw(enc) { }; MerkleBlock._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/mtx.js b/lib/bcoin/mtx.js index 8f823514..efaee05d 100644 --- a/lib/bcoin/mtx.js +++ b/lib/bcoin/mtx.js @@ -1058,7 +1058,7 @@ MTX._fromCompact = function _fromCompact(json) { assert.equal(json.type, 'tx'); raw = new Buffer(json.tx, 'hex'); - data = new bcoin.protocol.parser().parseTX(raw); + data = bcoin.protocol.parser.parseTX(raw); data.height = json.height; data.block = json.block; @@ -1134,7 +1134,7 @@ MTX.prototype.toRaw = function toRaw(enc) { }; MTX._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/output.js b/lib/bcoin/output.js index 7d605e22..50c4ecff 100644 --- a/lib/bcoin/output.js +++ b/lib/bcoin/output.js @@ -307,7 +307,7 @@ Output.prototype.toRaw = function toRaw(enc) { }; Output._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex'); diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 0404abfb..5052f166 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -56,7 +56,84 @@ Framer.prototype.packet = function packet(cmd, payload) { return Buffer.concat([h, payload]); }; -Framer.prototype._addr = function addr(data, full) { +Framer.prototype.version = function version(packet) { + return this.packet('version', Framer.version(packet, this.agent)); +}; + +Framer.prototype.verack = function verack() { + return this.packet('verack', Framer.verack()); +}; + +Framer.prototype.inv = function inv(items) { + return this.packet('inv', Framer.inv(items)); +}; + +Framer.prototype.getData = function getData(items) { + return this.packet('getdata', Framer.getData(items)); +}; + +Framer.prototype.notFound = function notFound(items) { + return this.packet('notfound', Framer.notFound(items)); +}; + +Framer.prototype.ping = function ping(data) { + return this.packet('ping', Framer.ping(data)); +}; + +Framer.prototype.pong = function pong(data) { + return this.packet('pong', Framer.pong(data)); +}; + +Framer.prototype.filterLoad = function filterLoad(bloom, update) { + return this.packet('filterload', Framer.filterLoad(bloom, update)); +}; + +Framer.prototype.filterClear = function filterClear() { + return this.packet('filterclear', Framer.filterClear()); +}; + +Framer.prototype.getHeaders = function getHeaders(hashes, stop) { + return this.packet('getheaders', Framer.getHeaders(hashes, stop)); +}; + +Framer.prototype.getBlocks = function getBlocks(hashes, stop) { + return this.packet('getblocks', Framer.getBlocks(hashes, stop)); +}; + +Framer.prototype.utxo = +Framer.prototype.coin = function _coin(coin) { + return this.packet('utxo', Framer.coin(coin, false)); +}; + +Framer.prototype.tx = function tx(tx) { + return this.packet('tx', Framer.tx(block)); +}; + +Framer.prototype.block = function _block(block) { + return this.packet('block', Framer.block(block)); +}; + +Framer.prototype.merkleBlock = function merkleBlock(block) { + return this.packet('merkleblock', Framer.merkleBlock(block)); +}; + +Framer.prototype.headers = function headers(block) { + return this.packet('headers', Framer.headers(block)); +}; + +Framer.prototype.reject = function reject(details) { + return this.packet('reject', Framer.reject(details)); +}; + +Framer.prototype.addr = function addr(peers) { + return this.packet('addr', Framer.addr(peers)); +}; + +Framer.prototype.mempool = function mempool() { + return this.packet('mempool', Framer.mempool()); +}; + +Framer.address = function addr(data, full) { var p = new Buffer(26 + (full ? 4 : 0)); var off = 0; @@ -102,11 +179,14 @@ Framer.prototype._addr = function addr(data, full) { return p; }; -Framer.prototype.version = function version(packet) { +Framer.version = function version(packet, agent) { var off = 0; var p, i, remote, local; - p = new Buffer(85 + utils.sizeIntv(this.agent.length) + this.agent.length); + if (!agent) + agent = new Buffer(constants.userAgent, 'ascii'); + + p = new Buffer(85 + utils.sizeIntv(agent.length) + agent.length); if (!packet) packet = {}; @@ -121,11 +201,11 @@ Framer.prototype.version = function version(packet) { off += utils.write64(p, utils.now(), off); // Their address (recv) - remote = this._addr(packet.remote || {}); + remote = Framer.address(packet.remote || {}); off += utils.copy(remote, p, off); // Our address (from) - local = this._addr(packet.local || {}); + local = Framer.address(packet.local || {}); off += utils.copy(local, p, off); // Nonce, very dramatic @@ -134,8 +214,8 @@ Framer.prototype.version = function version(packet) { assert.equal(off, 80); // User-agent - off += utils.writeIntv(p, this.agent.length, off); - off += utils.copy(this.agent, p, off); + off += utils.writeIntv(p, agent.length, off); + off += utils.copy(agent, p, off); // Start height off += utils.writeU32(p, packet.height || 0, off); @@ -145,14 +225,14 @@ Framer.prototype.version = function version(packet) { assert(off === p.length); - return this.packet('version', p); + return p; }; -Framer.prototype.verack = function verack() { - return this.packet('verack', new Buffer([])); +Framer.verack = function verack() { + return new Buffer([]); }; -Framer.prototype._inv = function _inv(command, items) { +Framer._inv = function _inv(items) { var p, i, hash; var off = 0; @@ -174,34 +254,34 @@ Framer.prototype._inv = function _inv(command, items) { off += utils.copy(hash, p, off); } - return this.packet(command, p); + return p; }; -Framer.prototype.inv = function inv(items) { - return this._inv('inv', items); +Framer.inv = function inv(items) { + return Framer._inv(items); }; -Framer.prototype.getData = function getData(items) { - return this._inv('getdata', items); +Framer.getData = function getData(items) { + return Framer._inv(items); }; -Framer.prototype.notFound = function notFound(items) { - return this._inv('notfound', items); +Framer.notFound = function notFound(items) { + return Framer._inv(items); }; -Framer.prototype.ping = function ping(data) { +Framer.ping = function ping(data) { var p = new Buffer(8); utils.writeU64(p, data.nonce, 0); - return this.packet('ping', p); + return p; }; -Framer.prototype.pong = function pong(data) { +Framer.pong = function pong(data) { var p = new Buffer(8); utils.writeU64(p, data.nonce, 0); - return this.packet('pong', p); + return p; }; -Framer.prototype.filterLoad = function filterLoad(bloom, update) { +Framer.filterLoad = function filterLoad(bloom, update) { var filter = bloom.toBuffer(); var p = new Buffer(utils.sizeIntv(filter.length) + filter.length + 9); var off = 0; @@ -218,31 +298,31 @@ Framer.prototype.filterLoad = function filterLoad(bloom, update) { // nFlags p[off++] = constants.filterFlags[update]; - return this.packet('filterload', p); + return p; }; -Framer.prototype.filterClear = function filterClear() { - return this.packet('filterclear', new Buffer([])); +Framer.filterClear = function filterClear() { + return new Buffer([]); }; -Framer.prototype.getHeaders = function getHeaders(hashes, stop) { - return this._getBlocks('getheaders', hashes, stop); +Framer.getHeaders = function getHeaders(hashes, stop) { + // NOTE: getheaders can have a null hash + if (!hashes) + hashes = []; + + return Framer._getBlocks(hashes, stop); }; -Framer.prototype.getBlocks = function getBlocks(hashes, stop) { - return this._getBlocks('getblocks', hashes, stop); +Framer.getBlocks = function getBlocks(hashes, stop) { + return Framer._getBlocks(hashes, stop); }; -Framer.prototype._getBlocks = function _getBlocks(cmd, hashes, stop) { +Framer._getBlocks = function _getBlocks(hashes, stop) { var p, i, hash, len; var off = 0; p = new Buffer(4 + utils.sizeIntv(hashes.length) + 32 * (hashes.length + 1)); - // getheaders can have a null hash - if (cmd === 'getheaders' && !hashes) - hashes = []; - off += utils.writeU32(p, constants.version, off); off += utils.writeIntv(p, hashes.length, off); @@ -253,9 +333,7 @@ Framer.prototype._getBlocks = function _getBlocks(cmd, hashes, stop) { hash = new Buffer(hash, 'hex'); len = utils.copy(hash, p, off); - - for (; len < 32; len++) - p[off + len] = 0; + assert(len === 32); off += len; } @@ -264,16 +342,16 @@ Framer.prototype._getBlocks = function _getBlocks(cmd, hashes, stop) { if (typeof stop === 'string') stop = new Buffer(stop, 'hex'); len = utils.copy(stop, p, off); + assert(len === 32); } else { len = 0; + for (; len < 32; len++) + p[off + len] = 0; } - for (; len < 32; len++) - p[off + len] = 0; - assert.equal(off + len, p.length); - return this.packet(cmd, p); + return p; }; Framer.input = function _input(input) { @@ -310,6 +388,7 @@ Framer.output = function _output(output) { return p; }; +Framer.utxo = Framer.coin = function _coin(coin, extended) { var script = bcoin.script.encode(coin.script); var intSize = utils.sizeIntv(script.length); @@ -382,10 +461,6 @@ Framer.tx = function _tx(tx) { return p; }; -Framer.prototype.tx = function tx(tx) { - return this.packet('tx', Framer.tx(tx)); -}; - Framer.block = function _block(block) { var off = 0; var txSize = 0; @@ -512,19 +587,7 @@ Framer.headers = function _headers(block) { return p; }; -Framer.prototype.block = function _block(block) { - return this.packet('block', Framer.block(block)); -}; - -Framer.prototype.merkleBlock = function merkleBlock(block) { - return this.packet('merkleblock', Framer.merkleBlock(block)); -}; - -Framer.prototype.headers = function headers(block) { - return this.packet('headers', Framer.headers(block)); -}; - -Framer.prototype.reject = function reject(details) { +Framer.reject = function reject(details) { var message = new Buffer(details.message || '', 'ascii'); var ccode = constants.reject[details.ccode] || constants.reject.malformed; var reason = new Buffer(details.reason || '', 'ascii'); @@ -546,10 +609,10 @@ Framer.prototype.reject = function reject(details) { off += utils.copy(data, p, off); - return this.packet('reject', p); + return p; }; -Framer.prototype.addr = function addr(peers) { +Framer.addr = function addr(peers) { var p = new Buffer(utils.sizeIntv(peers.length) + peers.length * 30); var off = 0; var addrs = []; @@ -561,7 +624,7 @@ Framer.prototype.addr = function addr(peers) { for (i = 0; i < peers.length; i++) { peer = peers[i]; - addr = this._addr({ + addr = Framer.address({ ts: peer.ts, services: peer.services, ipv6: peer.ipv6, @@ -572,11 +635,11 @@ Framer.prototype.addr = function addr(peers) { off += addr.copy(p, off, 0, addr.length); } - return this.packet('addr', p); + return p; }; -Framer.prototype.mempool = function mempool() { - return this.packet('mempool', new Buffer([])); +Framer.mempool = function mempool() { + return new Buffer([]); }; /** diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index cd12258a..6cfa9c40 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -77,7 +77,12 @@ Parser.prototype.parse = function parse(chunk) { if (utils.readU32(utils.checksum(this.packet.payload)) !== this.packet.checksum) return this._error('Invalid checksum'); - this.packet.payload = this.parsePayload(this.packet.cmd, this.packet.payload); + try { + this.packet.payload = this.parsePayload(this.packet.cmd, this.packet.payload); + } catch (e) { + this.emit('error', e); + } + if (this.packet.payload) this.emit('packet', this.packet); @@ -112,64 +117,64 @@ Parser.prototype.parseHeader = function parseHeader(h) { Parser.prototype.parsePayload = function parsePayload(cmd, p) { if (cmd === 'version') - return this.parseVersion(p); + return Parser.parseVersion(p); if (cmd === 'getdata' || cmd === 'inv' || cmd === 'notfound') - return this.parseInvList(p); + return Parser.parseInvList(p); if (cmd === 'merkleblock') - return this.parseMerkleBlock(p); + return Parser.parseMerkleBlock(p); if (cmd === 'headers') - return this.parseHeaders(p); + return Parser.parseHeaders(p); // if (cmd === 'block') - // return this.parseBlock(p); + // return Parser.parseBlock(p); if (cmd === 'block') - return this.parseBlockCompact(p); + return Parser.parseBlockCompact(p); if (cmd === 'tx') - return this.parseTX(p); + return Parser.parseTX(p); if (cmd === 'reject') - return this.parseReject(p); + return Parser.parseReject(p); if (cmd === 'addr') - return this.parseAddr(p); + return Parser.parseAddr(p); if (cmd === 'ping') - return this.parsePing(p); + return Parser.parsePing(p); if (cmd === 'pong') - return this.parsePong(p); + return Parser.parsePong(p); return p; }; -Parser.prototype.parsePing = function parsePing(p) { +Parser.parsePing = function parsePing(p) { if (p.length < 8) - return this._error('pong packet is too small'); + throw new Error('pong packet is too small'); return { nonce: utils.readU64(p, 0) }; }; -Parser.prototype.parsePong = function parsePong(p) { +Parser.parsePong = function parsePong(p) { if (p.length < 8) - return this._error('ping packet is too small'); + throw new Error('ping packet is too small'); return { nonce: utils.readU64(p, 0) }; }; -Parser.prototype.parseVersion = function parseVersion(p) { +Parser.parseVersion = function parseVersion(p) { var v, services, ts, recv, from, nonce, result, off, agent, height, relay; if (p.length < 85) - return this._error('version packet is too small'); + throw new Error('version packet is too small'); v = utils.readU32(p, 0); services = utils.readU64(p, 4); @@ -178,10 +183,10 @@ Parser.prototype.parseVersion = function parseVersion(p) { ts = utils.read64(p, 12); // Our address (recv) - recv = this._parseAddr(p, 20); + recv = Parser.parseAddress(p, 20); // Their Address (from) - from = this._parseAddr(p, 46); + from = Parser.parseAddress(p, 46); // Nonce, very dramatic nonce = utils.readU64(p, 72); @@ -224,7 +229,7 @@ Parser.prototype.parseVersion = function parseVersion(p) { }; }; -Parser.prototype.parseInvList = function parseInvList(p) { +Parser.parseInvList = function parseInvList(p) { var items = []; var i, off, count; @@ -233,7 +238,7 @@ Parser.prototype.parseInvList = function parseInvList(p) { count = count.r; if (p.length < count * 36) - return this._error('Invalid getdata size'); + throw new Error('Invalid getdata size'); for (i = 0, off = 0; i < count; i++, off += 36) { items.push({ @@ -245,18 +250,18 @@ Parser.prototype.parseInvList = function parseInvList(p) { return items; }; -Parser.prototype.parseMerkleBlock = function parseMerkleBlock(p) { +Parser.parseMerkleBlock = function parseMerkleBlock(p) { var i, hashCount, off, hashes, flagCount, flags; if (p.length < 86) - return this._error('Invalid merkleblock size'); + throw new Error('Invalid merkleblock size'); hashCount = utils.readIntv(p, 84); off = hashCount.off; hashCount = hashCount.r; if (off + 32 * hashCount + 1 > p.length) - return this._error('Invalid hash count'); + throw new Error('Invalid hash count'); hashes = new Array(hashCount); @@ -269,7 +274,7 @@ Parser.prototype.parseMerkleBlock = function parseMerkleBlock(p) { flagCount = flagCount.r; if (off + flagCount > p.length) - return this._error('Invalid flag count'); + throw new Error('Invalid flag count'); flags = p.slice(off, off + flagCount); @@ -288,19 +293,19 @@ Parser.prototype.parseMerkleBlock = function parseMerkleBlock(p) { }; }; -Parser.prototype.parseHeaders = function parseHeaders(p) { +Parser.parseHeaders = function parseHeaders(p) { var headers = []; var i, result, off, count, header, start, r; if (p.length < 81) - return this._error('Invalid headers size'); + throw new Error('Invalid headers size'); result = utils.readIntv(p, 0); off = result.off; count = result.r; if (p.length < count * 80) - return this._error('Invalid headers size'); + throw new Error('Invalid headers size'); for (i = 0; i < count; i++) { header = {}; @@ -327,21 +332,21 @@ Parser.prototype.parseHeaders = function parseHeaders(p) { return headers; }; -Parser.prototype.parseBlock = function parseBlock(p) { +Parser.parseBlock = function parseBlock(p) { var txs = []; var i, result, off, totalTX, tx; if (p.length < 81) - return this._error('Invalid block size'); + throw new Error('Invalid block size'); result = utils.readIntv(p, 80); off = result.off; totalTX = result.r; for (i = 0; i < totalTX; i++) { - tx = this.parseTX(p.slice(off)); + tx = Parser.parseTX(p.slice(off)); if (!tx) - return this._error('Invalid tx count for block'); + throw new Error('Invalid tx count for block'); tx._offset = off; off += tx._size; txs.push(tx); @@ -361,13 +366,13 @@ Parser.prototype.parseBlock = function parseBlock(p) { }; }; -Parser.prototype.parseBlockCompact = function parseBlockCompact(p) { +Parser.parseBlockCompact = function parseBlockCompact(p) { var height = -1; var i, result, off, totalTX, tx; var inCount, input, s, version; if (p.length < 81) - return this._error('Invalid block size'); + throw new Error('Invalid block size'); version = utils.read32(p, 0); @@ -377,16 +382,16 @@ Parser.prototype.parseBlockCompact = function parseBlockCompact(p) { if (version > 1 && totalTX > 0) { if (p.length < off + 10) - return this._error('Invalid tx size'); + throw new Error('Invalid tx size'); inCount = utils.readIntv(p, off + 4); off = inCount.off; inCount = inCount.r; if (inCount > 0) { - input = this.parseInput(p.slice(off)); + input = Parser.parseInput(p.slice(off)); if (!input) - return this._error('Invalid tx count for block'); + throw new Error('Invalid tx count for block'); } } @@ -411,18 +416,18 @@ Parser.prototype.parseBlockCompact = function parseBlockCompact(p) { }; }; -Parser.prototype.parseInput = function parseInput(p) { +Parser.parseInput = function parseInput(p) { var scriptLen, off; if (p.length < 41) - return this._error('Invalid tx_in size'); + throw new Error('Invalid tx_in size'); scriptLen = utils.readIntv(p, 36); off = scriptLen.off; scriptLen = scriptLen.r; if (off + scriptLen + 4 > p.length) - return this._error('Invalid tx_in script length'); + throw new Error('Invalid tx_in script length'); return { _size: off + scriptLen + 4, @@ -435,18 +440,18 @@ Parser.prototype.parseInput = function parseInput(p) { }; }; -Parser.prototype.parseOutput = function parseOutput(p) { +Parser.parseOutput = function parseOutput(p) { var scriptLen, off; if (p.length < 9) - return this._error('Invalid tx_out size'); + throw new Error('Invalid tx_out size'); scriptLen = utils.readIntv(p, 8); off = scriptLen.off; scriptLen = scriptLen.r; if (off + scriptLen > p.length) - return this._error('Invalid tx_out script length'); + throw new Error('Invalid tx_out script length'); return { _size: off + scriptLen, @@ -455,7 +460,7 @@ Parser.prototype.parseOutput = function parseOutput(p) { }; }; -Parser.prototype.parseCoin = function parseCoin(p, extended) { +Parser.parseCoin = function parseCoin(p, extended) { var off = 0; var version, height, value, script, hash, index, spent, scriptLen; @@ -509,27 +514,27 @@ Parser.prototype.parseCoin = function parseCoin(p, extended) { }; }; -Parser.prototype.parseTX = function parseTX(p) { +Parser.parseTX = function parseTX(p) { var inCount, off, txIn, tx; var outCount, txOut; var i; if (p.length < 10) - return this._error('Invalid tx size'); + throw new Error('Invalid tx size'); inCount = utils.readIntv(p, 4); off = inCount.off; inCount = inCount.r; if (inCount < 0) - return this._error('Invalid tx_in count (negative)'); + throw new Error('Invalid tx_in count (negative)'); if (off + 41 * inCount + 5 > p.length) - return this._error('Invalid tx_in count (too big)'); + throw new Error('Invalid tx_in count (too big)'); txIn = new Array(inCount); for (i = 0; i < inCount; i++) { - tx = this.parseInput(p.slice(off)); + tx = Parser.parseInput(p.slice(off)); if (!tx) return; @@ -539,20 +544,20 @@ Parser.prototype.parseTX = function parseTX(p) { off += tx._size; if (off + 5 > p.length) - return this._error('Invalid tx_in offset'); + throw new Error('Invalid tx_in offset'); } outCount = utils.readIntv(p, off); off = outCount.off; outCount = outCount.r; if (outCount < 0) - return this._error('Invalid tx_out count (negative)'); + throw new Error('Invalid tx_out count (negative)'); if (off + 9 * outCount + 4 > p.length) - return this._error('Invalid tx_out count (too big)'); + throw new Error('Invalid tx_out count (too big)'); txOut = new Array(outCount); for (i = 0; i < outCount; i++) { - tx = this.parseOutput(p.slice(off)); + tx = Parser.parseOutput(p.slice(off)); if (!tx) return; @@ -562,7 +567,7 @@ Parser.prototype.parseTX = function parseTX(p) { off += tx._size; if (off + 4 > p.length) - return this._error('Invalid tx_out offset'); + throw new Error('Invalid tx_out offset'); } return { @@ -575,18 +580,18 @@ Parser.prototype.parseTX = function parseTX(p) { }; }; -Parser.prototype.parseReject = function parseReject(p) { +Parser.parseReject = function parseReject(p) { var messageLen, off, message, ccode, reasonLen, reason, data; if (p.length < 3) - return this._error('Invalid reject size'); + throw new Error('Invalid reject size'); messageLen = utils.readIntv(p, 0); off = messageLen.off; messageLen = messageLen.r; if (off + messageLen + 2 > p.length) - return this._error('Invalid reject message'); + throw new Error('Invalid reject message'); message = p.slice(off, off + messageLen).toString('ascii'); off += messageLen; @@ -599,7 +604,7 @@ Parser.prototype.parseReject = function parseReject(p) { reasonLen = reasonLen.r; if (off + reasonLen > p.length) - return this._error('Invalid reject reason'); + throw new Error('Invalid reject reason'); reason = p.slice(off, off + reasonLen).toString('ascii'); @@ -615,7 +620,7 @@ Parser.prototype.parseReject = function parseReject(p) { }; }; -Parser.prototype._parseAddr = function _parseAddr(p, off, full) { +Parser.parseAddress = function parseAddress(p, off, full) { var ts, services, ip, port; if (!off) @@ -652,9 +657,9 @@ Parser.prototype._parseAddr = function _parseAddr(p, off, full) { }; }; -Parser.prototype.parseAddr = function parseAddr(p) { +Parser.parseAddr = function parseAddr(p) { if (p.length < 31) - return this._error('Invalid addr size'); + throw new Error('Invalid addr size'); var addrs = []; var i, off, count; @@ -664,16 +669,16 @@ Parser.prototype.parseAddr = function parseAddr(p) { count = count.r; for (i = 0; i < count && off < p.length; i++) { - addrs.push(this._parseAddr(p, off, true)); + addrs.push(Parser.parseAddress(p, off, true)); off += 30; } return addrs; }; -Parser.prototype.parseMempool = function parseMempool(p) { +Parser.parseMempool = function parseMempool(p) { if (p.length > 0) - return this._error('Invalid mempool size'); + throw new Error('Invalid mempool size'); return {}; }; diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index bcce0be3..ccaf2760 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -774,7 +774,7 @@ TX._fromCompact = function _fromCompact(json) { assert.equal(json.type, 'tx'); raw = new Buffer(json.tx, 'hex'); - data = new bcoin.protocol.parser().parseTX(raw); + data = bcoin.protocol.parser.parseTX(raw); data.height = json.height; data.block = json.block; @@ -844,7 +844,7 @@ TX.prototype.toRaw = function toRaw(enc) { }; TX._fromRaw = function _fromRaw(data, enc) { - var parser = new bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; if (enc === 'hex') data = new Buffer(data, 'hex');