diff --git a/lib/primitives/outpoint.js b/lib/primitives/outpoint.js index d8cfd2a4..10292dd5 100644 --- a/lib/primitives/outpoint.js +++ b/lib/primitives/outpoint.js @@ -8,7 +8,7 @@ const assert = require('assert'); const util = require('../utils/util'); -const StaticWriter = require('../utils/writer'); +const StaticWriter = require('../utils/staticwriter'); const BufferReader = require('../utils/reader'); const encoding = require('../utils/encoding'); diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index 231f0bbb..46c2acae 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -451,7 +451,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) { // Calculate buffer size. const size = this.hashSize(index, prev, type); - const bw = new StaticWriter(size); + const bw = StaticWriter.pool(size); bw.writeU32(this.version); @@ -615,7 +615,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type if (this._hashPrevouts) { prevouts = this._hashPrevouts; } else { - const bw = new StaticWriter(this.inputs.length * 36); + const bw = StaticWriter.pool(this.inputs.length * 36); for (const input of this.inputs) input.prevout.toWriter(bw); @@ -633,7 +633,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type if (this._hashSequence) { sequences = this._hashSequence; } else { - const bw = new StaticWriter(this.inputs.length * 4); + const bw = StaticWriter.pool(this.inputs.length * 4); for (const input of this.inputs) bw.writeU32(input.sequence); @@ -655,7 +655,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type for (const output of this.outputs) size += output.getSize(); - const bw = new StaticWriter(size); + const bw = StaticWriter.pool(size); for (const output of this.outputs) output.toWriter(bw); @@ -673,7 +673,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type } const size = 156 + prev.getVarSize(); - const bw = new StaticWriter(size); + const bw = StaticWriter.pool(size); bw.writeU32(this.version); bw.writeBytes(prevouts); diff --git a/lib/utils/reader.js b/lib/utils/reader.js index 4323c17b..bbb82560 100644 --- a/lib/utils/reader.js +++ b/lib/utils/reader.js @@ -10,7 +10,8 @@ const assert = require('assert'); const encoding = require('./encoding'); const digest = require('../crypto/digest'); -const EMPTY_BUFFER = Buffer.alloc(0); + +const EMPTY = Buffer.alloc(0); /** * An object that allows reading of buffers in a sane manner. @@ -145,7 +146,7 @@ BufferReader.prototype.endData = function endData(zeroCopy) { */ BufferReader.prototype.destroy = function destroy() { - this.data = EMPTY_BUFFER; + this.data = EMPTY; this.offset = 0; this.stack.length = 0; }; diff --git a/lib/utils/staticwriter.js b/lib/utils/staticwriter.js index c90ad799..46040962 100644 --- a/lib/utils/staticwriter.js +++ b/lib/utils/staticwriter.js @@ -9,7 +9,9 @@ const assert = require('assert'); const encoding = require('./encoding'); const digest = require('../crypto/digest'); -const EMPTY_BUFFER = Buffer.alloc(0); + +const POOL = Buffer.allocUnsafeSlow(100 * 1024); +const EMPTY = Buffer.alloc(0); /** * Statically allocated buffer writer. @@ -22,24 +24,34 @@ function StaticWriter(size) { if (!(this instanceof StaticWriter)) return new StaticWriter(size); - this.data = Buffer.allocUnsafe(size); + this.data = size ? Buffer.allocUnsafe(size) : EMPTY; this.offset = 0; } +/** + * Allocate writer from preallocated 100kb pool. + * @param {Number} size + * @returns {StaticWriter} + */ + +StaticWriter.pool = function pool(size) { + if (size <= POOL.length) { + const bw = new StaticWriter(0); + bw.data = POOL.slice(0, size); + return bw; + } + return new StaticWriter(size); +}; + /** * Allocate and render the final buffer. - * @param {Boolean?} keep - Do not destroy the writer. * @returns {Buffer} Rendered buffer. */ -StaticWriter.prototype.render = function render(keep) { +StaticWriter.prototype.render = function render() { const data = this.data; - assert(this.offset === data.length); - - if (!keep) - this.destroy(); - + this.destroy(); return data; }; @@ -66,7 +78,7 @@ StaticWriter.prototype.seek = function seek(offset) { */ StaticWriter.prototype.destroy = function destroy() { - this.data = EMPTY_BUFFER; + this.data = EMPTY; this.offset = 0; }; diff --git a/lib/utils/writer.js b/lib/utils/writer.js index 96da456e..700cfdbd 100644 --- a/lib/utils/writer.js +++ b/lib/utils/writer.js @@ -71,11 +71,10 @@ function BufferWriter() { /** * Allocate and render the final buffer. - * @param {Boolean?} keep - Do not destroy the writer. * @returns {Buffer} Rendered buffer. */ -BufferWriter.prototype.render = function render(keep) { +BufferWriter.prototype.render = function render() { const data = Buffer.allocUnsafe(this.offset); let off = 0; @@ -183,8 +182,7 @@ BufferWriter.prototype.render = function render(keep) { assert(off === data.length); - if (!keep) - this.destroy(); + this.destroy(); return data; };