From 94b20355ea3e570eb91a67f02b8e8ba92ffa6cdb Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 15 Mar 2016 02:36:55 -0700 Subject: [PATCH] more framing and parsing. --- lib/bcoin/protocol/framer.js | 49 ++++++++++------- lib/bcoin/protocol/parser.js | 1 + lib/bcoin/tx.js | 100 ++++++++++------------------------- test/block-test.js | 2 +- test/protocol-test.js | 4 +- 5 files changed, 62 insertions(+), 94 deletions(-) diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 4a3a0720..987fbe66 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -494,7 +494,7 @@ Framer.witnessTX = function _witnessTX(tx, writer) { p.writeUIntv(tx.outputs.length); - for (i = 0; i < outputs.length; i++) + for (i = 0; i < tx.outputs.length; i++) Framer.output(tx.outputs[i], p); for (i = 0; i < tx.inputs.length; i++) { @@ -543,6 +543,33 @@ Framer.witnessBlock = function _witnessBlock(block, writer) { return Framer._block(block, true, writer); }; +Framer.renderTX = function renderTX(tx, useWitness, writer) { + var p = new BufferWriter(writer); + + if (tx._raw) { + if (!useWitness && bcoin.protocol.parser.isWitnessTX(tx._raw)) { + Framer.tx(tx, p); + witnessSize = p._witnessSize; + } else { + p.writeBytes(tx._raw); + witnessSize = tx._witnessSize; + } + } else { + if (useWitness && bcoin.tx.prototype.hasWitness.call(tx)) + Framer.witnessTX(tx, p); + else + Framer.tx(tx, p); + witnessSize = p._witnessSize; + } + + if (!writer) + p = p.render(); + + p._witnessSize = witnessSize; + + return p; +}; + Framer._block = function _block(block, useWitness, writer) { var p = new BufferWriter(writer); var witnessSize = 0; @@ -557,23 +584,8 @@ Framer._block = function _block(block, useWitness, writer) { p.writeIntv(block.txs.length); for (i = 0; i < block.txs.length; i++) { - tx = block.txs[i]; - - if (tx._raw) { - if (!useWitness && bcoin.protocol.parser.isWitnessTX(tx._raw)) { - Framer.tx(tx, p); - witnessSize += p._witnessSize; - } else { - p.writeBytes(tx._raw); - witnessSize += tx._witnessSize; - } - } else { - if (useWitness && bcoin.tx.prototype.hasWitness.call(tx)) - Framer.witnessTX(tx, p); - else - Framer.tx(tx, p); - witnessSize += p._witnessSize; - } + Framer.renderTX(block.txs[i], useWitness, p); + witnessSize += p._witnessSize; } if (!writer) @@ -832,4 +844,5 @@ BufferWriter.prototype.writeUIntv = function writeUIntv(value) { * Expose */ +Framer.BufferWriter = BufferWriter; module.exports = Framer; diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 345fd52e..ba98ac38 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -893,4 +893,5 @@ BufferReader.prototype.readUIntv = function readUIntv() { * Expose */ +Parser.BufferReader = BufferReader; module.exports = Parser; diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 3ddefbe0..0fc48ad1 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -1058,14 +1058,10 @@ TX.fromRaw = function fromRaw(data, enc) { }; TX.prototype.toExtended = function toExtended(saveCoins) { - var tx = this.render(); - var size = tx.length + 4 + 32 + 4 + 4 + 4; - var block = this.block ? new Buffer(this.block, 'hex') : constants.zeroHash; var height = this.height; var index = this.index; var changeIndex = this.changeIndex != null ? this.changeIndex : -1; - var off = 0; - var buf, coins; + var p = new bcoin.protocol.framer.BufferWriter(); if (height === -1) height = 0x7fffffff; @@ -1076,79 +1072,43 @@ TX.prototype.toExtended = function toExtended(saveCoins) { if (changeIndex === -1) changeIndex = 0x7fffffff; + bcoin.protocol.framer.renderTX(this, true, p); + p.writeU32(height); + p.writeHash(this.block || constants.zeroHash); + p.writeU32(this.index); + p.writeU32(this.ts); + p.writeU32(this.ps); + // p.writeU32(changeIndex); + if (saveCoins) { - coins = []; - size += utils.sizeIntv(this.inputs.length); + p.writeIntv(this.inputs.length); this.inputs.forEach(function(input) { - var coin; - if (!input.output) { - size += utils.sizeIntv(0); - coins.push(null); + p.writeVarBytes(new Buffer([])); return; } - coin = bcoin.protocol.framer.coin(input.output); - size += utils.sizeIntv(coin.length); - size += coin.length; - coins.push(coin); + bcoin.protocol.framer.coin(input.output, false, p); }); } - buf = new Buffer(size); - - off += utils.copy(tx, buf, off); - off += utils.writeU32(buf, height, off); - off += utils.copy(block, buf, off); - off += utils.writeU32(buf, this.index, off); - off += utils.writeU32(buf, this.ts, off); - off += utils.writeU32(buf, this.ps, off); - // off += utils.writeU32(buf, changeIndex, off); - - if (saveCoins) { - off += utils.writeIntv(buf, this.inputs.length, off); - coins.forEach(function(coin) { - if (!coin) { - off += utils.writeIntv(buf, 0, off); - return; - } - - off += utils.writeIntv(buf, coin.length, off); - off += utils.copy(coin, buf, off); - }); - } - - assert(off === buf.length); - - buf._witnessSize = tx._witnessSize; - buf._size = tx._size; - buf._extendedSize = off; - - return buf; + return p.render(); }; TX._fromExtended = function _fromExtended(buf, saveCoins) { - var tx, coinCount, chunkSize, coin, i; - var off = 0; + var p = new bcoin.protocol.parser.BufferReader(buf); + var tx, coinCount, coin, i; - tx = bcoin.protocol.parser.parseTX(buf); - off = tx._size; + p.start(); - if (buf.length === tx._size) - throw new Error('Not extended.'); + tx = bcoin.protocol.parser.parseTX(p); - tx.height = utils.readU32(buf, off); - off += 4; - tx.block = buf.slice(off, off + 32).toString('hex'); - off += 32; - tx.index = utils.readU32(buf, off); - off += 4; - tx.ts = utils.readU32(buf, off); - off += 4; - tx.ps = utils.readU32(buf, off); - off += 4; - // tx.changeIndex = utils.readU32(buf, off); - // off += 4; + tx.height = p.readU32(); + tx.block = p.readHash().toString('hex'); + tx.index = p.readU32(); + tx.ts = p.readU32(); + tx.ps = p.readU32(); + // tx.changeIndex = p.readU32(); if (+tx.block === 0) tx.block = null; @@ -1163,18 +1123,12 @@ TX._fromExtended = function _fromExtended(buf, saveCoins) { tx.changeIndex = -1; if (saveCoins) { - coinCount = utils.readIntv(buf, off); - off = coinCount.off; - coinCount = coinCount.r; + coinCount = p.readUIntv(); for (i = 0; i < coinCount; i++) { - chunkSize = utils.readIntv(buf, off); - off = chunkSize.off; - chunkSize = chunkSize.r; - coin = buf.slice(off, off + chunkSize); - off += chunkSize; + coin = p.readVarBytes(); if (coin.length === 0) continue; - coin = bcoin.protocol.parser.parseCoin(coin); + coin = bcoin.protocol.parser.parseCoin(p, false); coin.hash = tx.inputs[i].prevout.hash; coin.index = tx.inputs[i].prevout.index; coin.spent = false; @@ -1182,7 +1136,7 @@ TX._fromExtended = function _fromExtended(buf, saveCoins) { } } - tx._extendedSize = off; + p.end(); return tx; }; diff --git a/test/block-test.js b/test/block-test.js index 2d0a6c7e..2a45a05e 100644 --- a/test/block-test.js +++ b/test/block-test.js @@ -24,7 +24,7 @@ describe('Block', function() { '5adbf04583354515a225f2c418de7c5cdac4cef211820c79717cd2c50412153f', '1f5e46b9da3a8b1241f4a1501741d3453bafddf6135b600b926e3f4056c6d564', '33825657ba32afe269819f01993bd77baba86379043168c94845d32370e53562' ], - flags: [ 245, 90, 0 ] + flags: new Buffer([ 245, 90, 0 ]) }, 'merkleblock'); var raw = bcoin.utils.toHex(block.toRaw()); diff --git a/test/protocol-test.js b/test/protocol-test.js index 9665e86a..f57cafff 100644 --- a/test/protocol-test.js +++ b/test/protocol-test.js @@ -26,14 +26,14 @@ describe('Protocol', function() { } packetTest('version', {}, function(payload) { - assert.equal(payload.v, 70002); + assert.equal(payload.version, 70002); assert.equal(payload.agent, agent); assert.equal(payload.height, 0); assert.equal(payload.relay, false); }); packetTest('version', { relay: true, height: 10 }, function(payload) { - assert.equal(payload.v, 70002); + assert.equal(payload.version, 70002); assert.equal(payload.agent, agent); assert.equal(payload.height, 10); assert.equal(payload.relay, true);