refactor and comments/explanation.

This commit is contained in:
Christopher Jeffrey 2016-04-20 13:08:42 -07:00
parent cbe2e2f28d
commit 11ef30b942
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -1982,18 +1982,18 @@ Script.array = function(value) {
Script.prototype.removeData = function removeData(data) { Script.prototype.removeData = function removeData(data) {
var total = 0; var total = 0;
var op, sig, raw, i, a, b; var opcode, sig, raw, i, a, b;
if (!this.raw) if (!this.raw)
return this.removeDataFast(data); return this.removeDataFast(data);
// We need to reserialize // We need to reserialize
// the signature as minimaldata. // the signature as minimaldata.
op = data.op; opcode = data.opcode;
delete data.op; delete data.opcode;
sig = Script.encode([data]); sig = Script.encode([data]);
if (op != null) if (opcode != null)
utils.hidden(data, 'op', op); data.opcode = opcode;
raw = this.encode(); raw = this.encode();
@ -2080,7 +2080,7 @@ Script.checkMinimal = function checkMinimal(value, flags) {
if (!(flags & constants.flags.VERIFY_MINIMALDATA)) if (!(flags & constants.flags.VERIFY_MINIMALDATA))
return true; return true;
if (value.op == null) if (value.opcode == null)
return true; return true;
if (value.length === 1 && value[0] >= 1 && value[0] <= 16) if (value.length === 1 && value[0] >= 1 && value[0] <= 16)
@ -2090,13 +2090,13 @@ Script.checkMinimal = function checkMinimal(value, flags) {
return false; return false;
if (value.length <= 75) if (value.length <= 75)
return value.op === value.length; return value.opcode === value.length;
if (value.length <= 255) if (value.length <= 255)
return value.op === opcodes.OP_PUSHDATA1; return value.opcode === opcodes.OP_PUSHDATA1;
if (value.length <= 65535) if (value.length <= 65535)
return value.op === opcodes.OP_PUSHDATA2; return value.opcode === opcodes.OP_PUSHDATA2;
return true; return true;
}; };
@ -4040,16 +4040,6 @@ Script.fromRaw = function fromRaw(data, enc) {
* @returns {Array} Script code. * @returns {Array} Script code.
*/ */
Script.isBadPush = function isBadPush(op) {
if (Buffer.isBuffer(op))
return false;
if (op >= 0x01 && op <= 0x4b)
return true;
if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4)
return true;
return false;
};
Script.decode = function decode(buf) { Script.decode = function decode(buf) {
var code = []; var code = [];
var p = new BufferReader(buf, true); var p = new BufferReader(buf, true);
@ -4068,7 +4058,7 @@ Script.decode = function decode(buf) {
continue; continue;
} }
data = p.readBytes(op); data = p.readBytes(op);
utils.hidden(data, 'op', op); data.opcode = op;
code.push(data); code.push(data);
} else if (op === opcodes.OP_PUSHDATA1) { } else if (op === opcodes.OP_PUSHDATA1) {
if (p.left() < 1) { if (p.left() < 1) {
@ -4086,7 +4076,7 @@ Script.decode = function decode(buf) {
continue; continue;
} }
data = p.readBytes(size); data = p.readBytes(size);
utils.hidden(data, 'op', op); data.opcode = op;
code.push(data); code.push(data);
} else if (op === opcodes.OP_PUSHDATA2) { } else if (op === opcodes.OP_PUSHDATA2) {
if (p.left() < 2) { if (p.left() < 2) {
@ -4105,7 +4095,7 @@ Script.decode = function decode(buf) {
continue; continue;
} }
data = p.readBytes(size); data = p.readBytes(size);
utils.hidden(data, 'op', op); data.opcode = op;
code.push(data); code.push(data);
} else if (op === opcodes.OP_PUSHDATA4) { } else if (op === opcodes.OP_PUSHDATA4) {
if (p.left() < 4) { if (p.left() < 4) {
@ -4126,7 +4116,7 @@ Script.decode = function decode(buf) {
continue; continue;
} }
data = p.readBytes(size); data = p.readBytes(size);
utils.hidden(data, 'op', op); data.opcode = op;
code.push(data); code.push(data);
} else { } else {
code.push(op); code.push(op);
@ -4136,7 +4126,6 @@ Script.decode = function decode(buf) {
return code; return code;
}; };
/** /**
* Encode and serialize script code. This will _not_ * Encode and serialize script code. This will _not_
* include the varint size at the start. This will * include the varint size at the start. This will
@ -4162,19 +4151,19 @@ Script.encode = function encode(code, writer) {
if (Buffer.isBuffer(op)) { if (Buffer.isBuffer(op)) {
// Check for nonstandard pushdatas that // Check for nonstandard pushdatas that
// may have been decoded from before. // may have been decoded from before.
if (op.op != null) { if (op.opcode != null) {
if (op.op <= 0x4b) { if (op.opcode <= 0x4b) {
p.writeU8(op.length); p.writeU8(op.length);
p.writeBytes(op); p.writeBytes(op);
} else if (op.op === opcodes.OP_PUSHDATA1) { } else if (op.opcode === opcodes.OP_PUSHDATA1) {
p.writeU8(opcodes.OP_PUSHDATA1); p.writeU8(opcodes.OP_PUSHDATA1);
p.writeU8(op.length); p.writeU8(op.length);
p.writeBytes(op); p.writeBytes(op);
} else if (op.op === opcodes.OP_PUSHDATA2) { } else if (op.opcode === opcodes.OP_PUSHDATA2) {
p.writeU8(opcodes.OP_PUSHDATA2); p.writeU8(opcodes.OP_PUSHDATA2);
p.writeU16(op.length); p.writeU16(op.length);
p.writeBytes(op); p.writeBytes(op);
} else if (op.op === opcodes.OP_PUSHDATA4) { } else if (op.opcode === opcodes.OP_PUSHDATA4) {
p.writeU8(opcodes.OP_PUSHDATA4); p.writeU8(opcodes.OP_PUSHDATA4);
p.writeU32(op.length); p.writeU32(op.length);
p.writeBytes(op); p.writeBytes(op);
@ -4230,6 +4219,47 @@ Script.encode = function encode(code, writer) {
return p; return p;
}; };
/**
* Determine whether GetOp2 should fail
* on a given op due to a bad push (either
* not enough size bytes after a PUSHDATA,
* or not enough data after the size.
*
* If bitcoind comes across a bad push, it
* will return an invalid opcode. The problem
* is bitcoind parses scripts _as_ they are
* executing, which can be slow for us because
* now every function that needs to test the
* script needs to parse the raw data. It's
* also impossible to read a script
* _backwards_ making testing for things like
* multisig outputs even more difficult.
*
* If BCoin comes accross a bad push in its
* initial parsing, it simply will _not
* consider the pushdata to be a pushdata_
* but just another opcode in the code array
* (all of the data after the pushdata op
* will also be considered opcodes rather
* than data). This function checks to see
* if an op is a direct push, or PUSHDATA1
* to PUSHDATA4 -- these opcodes cannot
* exist in the code array of valid parsed
* scripts.
* @param {Number|Buffer} op
* @returns {Boolean}
*/
Script.isBadPush = function isBadPush(op) {
if (Buffer.isBuffer(op))
return false;
if (op >= 0x01 && op <= 0x4b)
return true;
if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4)
return true;
return false;
};
/** /**
* Test an object to see if it is a Script. * Test an object to see if it is a Script.
* @param {Object} obj * @param {Object} obj