From 30148368a807cee18ca0d5e81691a1a8c3788163 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 27 Mar 2016 14:15:28 -0700 Subject: [PATCH] parsing. 64 bit ints. --- lib/bcoin/protocol/framer.js | 2 +- lib/bcoin/protocol/parser.js | 68 +++++++----------------------------- lib/bcoin/reader.js | 32 ++++++++++++----- lib/bcoin/utils.js | 36 ++++++++++++++++--- 4 files changed, 70 insertions(+), 68 deletions(-) diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 2a214304..4f8c265c 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -657,7 +657,7 @@ Framer.alert = function alert(data, writer) { if (data.signature) p.writeVarBytes(data.signature); else if (data.key) - p.writeVarBytes(bcoin.ec.sign(payload, data.key)); + p.writeVarBytes(bcoin.ec.sign(utils.dsha256(payload), data.key)); else assert(false, 'No key or signature.'); diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 751b184e..e7b2dceb 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -65,35 +65,6 @@ Parser.prototype.feed = function feed(data) { } }; -Parser.prototype._feed = function feed(data) { - var chunk; - - while (data) { - this.pendingTotal += data.length; - this.pending.push(data); - - if (this.pendingTotal < this.waiting) - return; - - if (this.pending.length === 1) - chunk = this.pending[0]; - else - chunk = Buffer.concat(this.pending); - - if (chunk.length > this.waiting) { - data = chunk.slice(this.waiting); - chunk = chunk.slice(0, this.waiting); - //chunk = utils.slice(chunk, 0, this.waiting); - } else { - data = null; - } - - this.pending.length = 0; - this.pendingTotal = 0; - this.parse(chunk); - } -}; - Parser.prototype.parse = function parse(chunk) { if (chunk.length > constants.maxMessage) return this._error('Packet too large: %dmb.', utils.mb(chunk.length)); @@ -212,8 +183,8 @@ Parser.parseVersion = function parseVersion(p) { p.start(); version = p.read32(); - services = p.readU64(); - ts = p.read64(); + services = p.readU53(); + ts = p.read53(); recv = Parser.parseAddress(p, false); from = Parser.parseAddress(p, false); nonce = p.readU64(); @@ -225,18 +196,6 @@ Parser.parseVersion = function parseVersion(p) { else relay = true; - try { - ts = ts.toNumber(); - } catch (e) { - ts = 0; - } - - try { - services = services.toNumber(); - } catch (e) { - services = 0; - } - assert(version >= 0, 'Version is negative.'); assert(ts >= 0, 'Timestamp is negative.'); assert(height >= 0, 'Height is negative.'); @@ -383,9 +342,8 @@ Parser.parseBlock = function parseBlock(p) { }; Parser.parseBlockCompact = function parseBlockCompact(p) { - var height = -1; var version, prevBlock, merkleRoot, ts, bits, nonce; - var totalTX; + var totalTX, height; var inCount, input, raw; p = new BufferReader(p); @@ -404,6 +362,12 @@ Parser.parseBlockCompact = function parseBlockCompact(p) { p.read32(); inCount = p.readVarint(); + if (inCount === 0) { + if (p.readU8() === 0) + throw new Error('Invalid witness tx (flag == 0)'); + inCount = p.readVarint(); + } + if (inCount > 0) input = Parser.parseInput(p); } @@ -700,18 +664,12 @@ Parser.parseAddress = function parseAddress(p, full) { else ts = 0; - services = p.readU64(); + services = p.readU53(); ip = p.readBytes(16); port = p.readU16BE(); - try { - services = services.toNumber(); - } catch (e) { - services = services.uand(utils.MAX_SAFE_BN).toNumber(); - } - return { ts: ts, services: services, @@ -761,14 +719,14 @@ Parser.parseAlert = function parseAlert(p) { size = p.end(); assert( - bcoin.ec.verify(payload, signature, network.alertKey), + bcoin.ec.verify(utils.dsha256(payload), signature, network.alertKey), 'Alert does not verify.'); p = new BufferReader(payload); p.start(); version = p.read32(); - relayUntil = p.read64(); - expiration = p.read64(); + relayUntil = p.read53(); + expiration = p.read53(); id = p.read32(); cancel = p.read32(); cancels = []; diff --git a/lib/bcoin/reader.js b/lib/bcoin/reader.js index 1b13eca0..1104f69d 100644 --- a/lib/bcoin/reader.js +++ b/lib/bcoin/reader.js @@ -115,20 +115,28 @@ BufferReader.prototype.readU64BE = function readU64BE() { return ret; }; -BufferReader.prototype.readU64N = function readU64N() { +BufferReader.prototype.readU64N = function readU64N(force53) { assert(this.offset + 8 <= this.data.length); - var ret = utils.readU64N(this.data, this.offset); + var ret = utils.readU64N(this.data, this.offset, force53); this.offset += 8; return ret; }; -BufferReader.prototype.readU64NBE = function readU64NBE() { +BufferReader.prototype.readU64NBE = function readU64NBE(force53) { assert(this.offset + 8 <= this.data.length); - var ret = utils.readU64NBE(this.data, this.offset); + var ret = utils.readU64NBE(this.data, this.offset, force53); this.offset += 8; return ret; }; +BufferReader.prototype.readU53 = function readU53() { + return this.readU64N(true); +}; + +BufferReader.prototype.readU53BE = function readU53BE() { + return this.readU64NBE(true); +}; + BufferReader.prototype.read8 = function read8() { assert(this.offset + 1 <= this.data.length); var ret = utils.read8(this.data, this.offset); @@ -178,20 +186,28 @@ BufferReader.prototype.read64BE = function read64BE() { return ret; }; -BufferReader.prototype.read64N = function read64N() { +BufferReader.prototype.read64N = function read64N(force53) { assert(this.offset + 8 <= this.data.length); - var ret = utils.read64N(this.data, this.offset); + var ret = utils.read64N(this.data, this.offset, force53); this.offset += 8; return ret; }; -BufferReader.prototype.read64NBE = function read64NBE() { +BufferReader.prototype.read64NBE = function read64NBE(force53) { assert(this.offset + 8 <= this.data.length); - var ret = utils.read64NBE(this.data, this.offset); + var ret = utils.read64NBE(this.data, this.offset, force53); this.offset += 8; return ret; }; +BufferReader.prototype.read53 = function read53() { + return this.read64N(true); +}; + +BufferReader.prototype.read53BE = function read53BE() { + return this.read64NBE(true); +}; + BufferReader.prototype.readBytes = function readBytes(size) { var ret; diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index 1a3b49b7..03bce93f 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -1292,50 +1292,78 @@ utils.write64NBE = function write64NBE(dst, num, off) { return 8; }; -utils.readU64N = function readU64N(dst, off) { +utils.readU64N = function readU64N(dst, off, force53) { off = off >>> 0; var hi = utils.readU32(dst, off + 4); var lo = utils.readU32(dst, off); + if (force53) + hi &= utils.MAX_SAFE_HI; assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1'); return (hi * 0x100000000) + lo; }; -utils.readU64NBE = function readU64NBE(dst, off) { +utils.readU64NBE = function readU64NBE(dst, off, force53) { off = off >>> 0; var hi = utils.readU32BE(dst, off); var lo = utils.readU32BE(dst, off + 4); + if (force53) + hi &= utils.MAX_SAFE_HI; assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1'); return (hi * 0x100000000) + lo; }; -utils.read64N = function read64N(dst, off) { +utils.read64N = function read64N(dst, off, force53) { off = off >>> 0; var hi = utils.readU32(dst, off + 4); var lo = utils.readU32(dst, off); if (hi & 0x80000000) { hi = ~hi + 1; lo = ~lo + 1; + if (force53) + hi &= utils.MAX_SAFE_HI; assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1'); return -(hi * 0x100000000 + lo); } + if (force53) + hi &= utils.MAX_SAFE_HI; assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1'); return (hi * 0x100000000) + lo; }; -utils.read64NBE = function read64NBE(dst, off) { +utils.read64NBE = function read64NBE(dst, off, force53) { off = off >>> 0; var hi = utils.readU32BE(dst, off); var lo = utils.readU32BE(dst, off + 4); if (hi & 0x80000000) { hi = ~hi + 1; lo = ~lo + 1; + if (force53) + hi &= utils.MAX_SAFE_HI; assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1'); return -(hi * 0x100000000 + lo); } + if (force53) + hi &= utils.MAX_SAFE_HI; assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1'); return (hi * 0x100000000) + lo; }; +utils.readU53 = function readU53(dst, off) { + return utils.readU64N(dst, off, true); +}; + +utils.readU53BE = function readU53BE(dst, off) { + return utils.readU64NBE(dst, off, true); +}; + +utils.read53 = function read53(dst, off) { + return utils.read64N(dst, off, true); +}; + +utils.read53BE = function read53BE(dst, off) { + return utils.read64NBE(dst, off, true); +}; + utils.write8 = function write8(dst, num, off) { num = +num; off = off >>> 0;