From 6c8c18f2a01cca565313d858654b42498359ab3a Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 20 Aug 2017 12:52:35 -0700 Subject: [PATCH] opcode: improve perf of opcode.from methods. --- lib/script/opcode.js | 183 ++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 108 deletions(-) diff --git a/lib/script/opcode.js b/lib/script/opcode.js index 98c1c107..1f7a1652 100644 --- a/lib/script/opcode.js +++ b/lib/script/opcode.js @@ -14,8 +14,7 @@ const common = require('./common'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const opcodes = common.opcodes; - -const cache = []; +const opCache = []; /** * A simple struct which contains @@ -180,92 +179,6 @@ Opcode.prototype.getSize = function getSize() { } }; -/** - * Inject properties from buffer reader. - * @param {BufferReader} br - * @private - */ - -Opcode.prototype.fromReader = function fromReader(br) { - const op = br.readU8(); - - if (op >= 0x01 && op <= 0x4b) { - if (br.left() < op) { - this.value = -1; - br.seek(br.left()); - return this; - } - this.value = op; - this.data = br.readBytes(op); - return this; - } - - let size; - - switch (op) { - case opcodes.OP_PUSHDATA1: - if (br.left() < 1) { - this.value = -1; - break; - } - size = br.readU8(); - if (br.left() < size) { - this.value = -1; - br.seek(br.left()); - break; - } - this.value = op; - this.data = br.readBytes(size); - break; - case opcodes.OP_PUSHDATA2: - if (br.left() < 2) { - this.value = -1; - br.seek(br.left()); - break; - } - size = br.readU16(); - if (br.left() < size) { - this.value = -1; - br.seek(br.left()); - break; - } - this.value = op; - this.data = br.readBytes(size); - break; - case opcodes.OP_PUSHDATA4: - if (br.left() < 4) { - this.value = -1; - br.seek(br.left()); - break; - } - size = br.readU32(); - if (br.left() < size) { - this.value = -1; - br.seek(br.left()); - break; - } - this.value = op; - this.data = br.readBytes(size); - break; - default: - this.value = op; - break; - } - - return this; -}; - -/** - * Inject properties from serialized data. - * @private - * @param {Buffer} data - * @returns {Opcode} - */ - -Opcode.prototype.fromRaw = function fromRaw(data) { - return this.fromReader(new BufferReader(data)); -}; - /** * Instantiate opcode from buffer reader. * @param {BufferReader} br @@ -273,17 +186,79 @@ Opcode.prototype.fromRaw = function fromRaw(data) { */ Opcode.fromReader = function fromReader(br) { - if (br.offset < br.data.length) { - const op = br.data[br.offset]; - const cached = cache[op]; + const value = br.readU8(); - if (cached) { - br.offset++; - return cached; + const cached = opCache[value]; + + if (cached) + return cached; + + const op = new Opcode(value, null); + + if (value >= 0x01 && value <= 0x4b) { + if (br.left() < value) { + op.value = -1; + br.seek(br.left()); + return op; } + op.value = value; + op.data = br.readBytes(value); + return op; } - return new Opcode(0, null).fromReader(br); + let size; + + switch (value) { + case opcodes.OP_PUSHDATA1: + if (br.left() < 1) { + op.value = -1; + break; + } + size = br.readU8(); + if (br.left() < size) { + op.value = -1; + br.seek(br.left()); + break; + } + op.value = value; + op.data = br.readBytes(size); + break; + case opcodes.OP_PUSHDATA2: + if (br.left() < 2) { + op.value = -1; + br.seek(br.left()); + break; + } + size = br.readU16(); + if (br.left() < size) { + op.value = -1; + br.seek(br.left()); + break; + } + op.value = value; + op.data = br.readBytes(size); + break; + case opcodes.OP_PUSHDATA4: + if (br.left() < 4) { + op.value = -1; + br.seek(br.left()); + break; + } + size = br.readU32(); + if (br.left() < size) { + op.value = -1; + br.seek(br.left()); + break; + } + op.value = value; + op.data = br.readBytes(size); + break; + default: + op.value = value; + break; + } + + return op; }; /** @@ -293,15 +268,7 @@ Opcode.fromReader = function fromReader(br) { */ Opcode.fromRaw = function fromRaw(data) { - if (data.length > 0) { - const op = data[0]; - const cached = cache[op]; - - if (cached) - return cached; - } - - return new Opcode(0, null).fromRaw(data); + return Opcode.fromReader(new BufferReader(data)); }; /** @@ -311,7 +278,7 @@ Opcode.fromRaw = function fromRaw(data) { */ Opcode.fromOp = function fromOp(op) { - const cached = cache[op]; + const cached = opCache[op]; if (cached) return cached; @@ -485,15 +452,15 @@ Opcode.isOpcode = function isOpcode(obj) { for (let value = 0x00; value <= 0xff; value++) { if (value >= 0x01 && value <= 0x4e) { - cache.push(null); + opCache.push(null); continue; } - const op = new Opcode(value); + const op = new Opcode(value, null); Object.freeze(op); - cache.push(op); + opCache.push(op); } /*