From ec21986062c88f8251f7fbd7d493729405fdc2e0 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 17 May 2016 12:47:16 -0700 Subject: [PATCH] optimize getProof. misc. --- lib/bcoin/block.js | 3 ++- lib/bcoin/chainentry.js | 16 ++++++++++++++-- lib/bcoin/mempool.js | 16 ++++++++++------ lib/bcoin/utils.js | 12 ++++++------ lib/bcoin/workers.js | 5 +++++ scripts/gen.js | 2 +- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 44fbff26..894f1194 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -481,7 +481,8 @@ Block.reward = function reward(height, network) { network = bcoin.network.get(network); halvings = height / network.halvingInterval | 0; - // BIP 42 + // BIP 42 (not technically necessary since we + // don't suffer from the undefined behavior of C++). // https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki if (halvings >= 64) return 0; diff --git a/lib/bcoin/chainentry.js b/lib/bcoin/chainentry.js index 016adf1f..2a1b3043 100644 --- a/lib/bcoin/chainentry.js +++ b/lib/bcoin/chainentry.js @@ -59,6 +59,13 @@ function ChainEntry(chain, data, prev) { this.chainwork = data.chainwork || this.getChainwork(prev); } +/** + * The max chainwork (1 << 256). + * @const {BN} + */ + +ChainEntry.MAX_CHAINWORK = new bn(1).ushln(256); + /** * Calculate the proof: (1 << 256) / (target + 1) * @returns {BN} proof @@ -68,7 +75,7 @@ ChainEntry.prototype.getProof = function getProof() { var target = utils.fromCompact(this.bits); if (target.isNeg() || target.cmpn(0) === 0) return new bn(0); - return new bn(1).ushln(256).div(target.addn(1)); + return ChainEntry.MAX_CHAINWORK.div(target.iaddn(1)); }; /** @@ -78,7 +85,12 @@ ChainEntry.prototype.getProof = function getProof() { */ ChainEntry.prototype.getChainwork = function getChainwork(prev) { - return (prev ? prev.chainwork : new bn(0)).add(this.getProof()); + var proof = this.getProof(); + + if (!prev) + return proof; + + return proof.iadd(prev.chainwork); }; /** diff --git a/lib/bcoin/mempool.js b/lib/bcoin/mempool.js index 88a53adf..b0eb00cb 100644 --- a/lib/bcoin/mempool.js +++ b/lib/bcoin/mempool.js @@ -1817,13 +1817,13 @@ MempoolEntry.fromTX = function fromTX(tx, height) { * can still be parsed as a regular tx since * the mempool entry data comes after the * serialized transaction. - * @param {TX} tx - * @param {Number} height - Entry height. - * @returns {MempoolEntry} + * @param {BufferWriter?} writer + * @returns {Buffer} */ -MempoolEntry.prototype.toRaw = function toRaw() { - var p = new BufferWriter(); +MempoolEntry.prototype.toRaw = function toRaw(writer) { + var p = new BufferWriter(writer); + bcoin.protocol.framer.renderTX(this.tx, true, p); p.writeU32(this.height); p.writeDouble(this.priority); @@ -1832,7 +1832,11 @@ MempoolEntry.prototype.toRaw = function toRaw() { p.writeU32(this.count); p.writeU32(this.size); p.writeVarint(this.fees); - return p.render(); + + if (!writer) + p = p.render(); + + return p; }; /** diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index 5ee2791f..2aec0c82 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -1966,15 +1966,15 @@ utils.write64 = function write64(dst, num, off) { off = off >>> 0; if (num.isNeg()) - num = num.neg().notn(64).addn(1); + num = num.neg().inotn(64).iaddn(1); if (num.bitLength() > 64) num = num.uand(utils.U64); - num = num.toBuffer('le', 8); + num = num.toArray('le', 8); for (i = 0; i < num.length; i++) - dst[off++] = num[i] & 0xff; + dst[off++] = num[i]; return 8; }; @@ -1996,15 +1996,15 @@ utils.write64BE = function write64BE(dst, num, off) { off = off >>> 0; if (num.isNeg()) - num = num.neg().notn(64).addn(1); + num = num.neg().inotn(64).iaddn(1); if (num.bitLength() > 64) num = num.uand(utils.U64); - num = num.toBuffer('be', 8); + num = num.toArray('be', 8); for (i = 0; i < num.length; i++) - dst[off++] = num[i] & 0xff; + dst[off++] = num[i]; return 8; }; diff --git a/lib/bcoin/workers.js b/lib/bcoin/workers.js index 84c793c7..bc0bdfb5 100644 --- a/lib/bcoin/workers.js +++ b/lib/bcoin/workers.js @@ -701,6 +701,9 @@ Framer.item = function _item(item, p) { } else if (item instanceof bcoin.chainentry) { p.writeU8(43); item.toRaw(p); + } else if (item instanceof bcoin.mempoolentry) { + p.writeU8(44); + item.toRaw(p); } else if (bn.isBN(item)) { p.writeU8(50); p.writeVarBytes(item.toBuffer()); @@ -859,6 +862,8 @@ Parser.parseItem = function parseItem(p) { return bcoin.coin.fromExtended(p); case 43: return bcoin.chainentry.fromRaw(null, p); + case 43: + return bcoin.mempoolentry.fromRaw(p); case 50: return new bn(p.readVarBytes()); default: diff --git a/scripts/gen.js b/scripts/gen.js index 75504f6a..0def9546 100644 --- a/scripts/gen.js +++ b/scripts/gen.js @@ -26,7 +26,7 @@ function createGenesisBlock(options) { } if (!options.reward) - options.reward = new bn(50).mul(constants.COIN); + options.reward = 50 * constants.COIN; tx = { version: 1,