From 62bab2bf326db46389a9b3a3849dd0a61bb6dcc5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 27 Apr 2016 20:14:36 -0700 Subject: [PATCH] O(n) sighashing. --- lib/bcoin/tx.js | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 5b5d7087..64728a57 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -468,13 +468,19 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, type) { assert(prev instanceof Script); if (!(type & constants.hashType.ANYONECANPAY)) { - hashPrevouts = new BufferWriter(); - for (i = 0; i < this.inputs.length; i++) { - prevout = this.inputs[i].prevout; - hashPrevouts.writeHash(prevout.hash); - hashPrevouts.writeU32(prevout.index); + if (this._hashPrevouts) { + hashPrevouts = this._hashPrevouts; + } else { + hashPrevouts = new BufferWriter(); + for (i = 0; i < this.inputs.length; i++) { + prevout = this.inputs[i].prevout; + hashPrevouts.writeHash(prevout.hash); + hashPrevouts.writeU32(prevout.index); + } + hashPrevouts = utils.dsha256(hashPrevouts.render()); + if (!this.mutable) + this._hashPrevouts = hashPrevouts; } - hashPrevouts = utils.dsha256(hashPrevouts.render()); } else { hashPrevouts = utils.slice(constants.ZERO_HASH); } @@ -482,20 +488,32 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, type) { if (!(type & constants.hashType.ANYONECANPAY) && (type & 0x1f) !== constants.hashType.SINGLE && (type & 0x1f) !== constants.hashType.NONE) { - hashSequence = new BufferWriter(); - for (i = 0; i < this.inputs.length; i++) - hashSequence.writeU32(this.inputs[i].sequence); - hashSequence = utils.dsha256(hashSequence.render()); + if (this._hashSequence) { + hashSequence = this._hashSequence; + } else { + hashSequence = new BufferWriter(); + for (i = 0; i < this.inputs.length; i++) + hashSequence.writeU32(this.inputs[i].sequence); + hashSequence = utils.dsha256(hashSequence.render()); + if (!this.mutable) + this._hashSequence = hashSequence; + } } else { hashSequence = utils.slice(constants.ZERO_HASH); } if ((type & 0x1f) !== constants.hashType.SINGLE && (type & 0x1f) !== constants.hashType.NONE) { - hashOutputs = new BufferWriter(); - for (i = 0; i < this.outputs.length; i++) - bcoin.protocol.framer.output(this.outputs[i], hashOutputs); - hashOutputs = utils.dsha256(hashOutputs.render()); + if (this._hashOutputs) { + hashOutputs = this._hashOutputs; + } else { + hashOutputs = new BufferWriter(); + for (i = 0; i < this.outputs.length; i++) + bcoin.protocol.framer.output(this.outputs[i], hashOutputs); + hashOutputs = utils.dsha256(hashOutputs.render()); + if (!this.mutable) + this._hashOutputs = hashOutputs; + } } else if ((type & 0x1f) === constants.hashType.SINGLE && index < this.outputs.length) { hashOutputs = bcoin.protocol.framer.output(this.outputs[index]); hashOutputs = utils.dsha256(hashOutputs);