test. fix sigops counting.

This commit is contained in:
Christopher Jeffrey 2016-04-20 13:14:38 -07:00
parent 11ef30b942
commit c1fd8bb285
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 72 additions and 60 deletions

View File

@ -2103,20 +2103,20 @@ Script.checkMinimal = function checkMinimal(value, flags) {
/**
* Test a buffer to see if it is valid script code (no non-existent opcodes).
* @param {Buffer} buf
* @param {Buffer} raw
* @returns {Boolean}
*/
Script.isCode = function isCode(buf) {
Script.isCode = function isCode(raw) {
var i, op, code;
if (!buf)
if (!raw)
return false;
if (!Buffer.isBuffer(buf))
if (!Buffer.isBuffer(raw))
return false;
code = Script.decode(buf);
code = Script.decode(raw);
for (i = 0; i < code.length; i++) {
op = code[i];
@ -3475,7 +3475,7 @@ Script.prototype.getSigops = function getSigops(accurate) {
continue;
if (Script.isBadPush(op))
return 0;
break;
if (op === opcodes.OP_CHECKSIG || op === opcodes.OP_CHECKSIGVERIFY) {
total++;
@ -4019,34 +4019,45 @@ Script.fromRaw = function fromRaw(data, enc) {
* Decode a serialized script into script code.
* Note that the serialized script must _not_
* include the varint size before it. Note that
* this will apply hidden `pushdata` properties
* this will apply hidden `opcode` properties
* to each Buffer if the buffer was created from
* a non-standard pushdata.
* a non-minimal pushdata.
*
* This function does not do bounds checking
* on buffers because some jackass could do a
* direct push of 30 bytes with only 20 bytes
* after it. That script would be perfectly
* fine _until_ it is executed. There are
* output scripts on the blockchain that can
* never be redeemed due to this, but they are
* in valid blocks, therefore we cannot fail
* parsing them.
* BCoin parses scripts "differently" because it
* parses them _before they're executed_. This
* lends itself to some interesting edge cases.
*
* 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 this function comes accross a bad push
* in its 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).
* Also note that this function uses reference
* Buffer slices. Larger buffer slices should
* _never_ be passed in here.
* @param {Buffer} buf - Serialized script.
* @param {Buffer} raw - Serialized script.
* @returns {Array} Script code.
*/
Script.decode = function decode(buf) {
Script.decode = function decode(raw) {
var p = new BufferReader(raw, true);
var code = [];
var p = new BufferReader(buf, true);
var off = 0;
var op, size;
var op, size, data;
assert(Buffer.isBuffer(buf));
assert(Buffer.isBuffer(raw));
while (p.left()) {
op = p.readU8();
@ -4225,26 +4236,10 @@ Script.encode = function encode(code, writer) {
* 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
* 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}

View File

@ -1042,23 +1042,6 @@ utils.merge = function merge(target) {
return target;
};
/**
* Set a non-enumerable property.
* @param {Object} obj
* @param {String} prop - Property name.
* @param value
*/
utils.hidden = function hidden(obj, prop, value) {
Object.defineProperty(obj, prop, {
value: value,
enumerable: false,
configurable: true,
writable: true
});
return obj;
};
/**
* Sort public keys lexicographically.
* @param {Buffer[]} keys

View File

@ -147,6 +147,8 @@ describe('Script', function() {
'OP_1 OP_DUP OP_PUSHDATA1'
);
assert(utils.equals(s.raw, new Buffer('51764c', 'hex')));
delete s.raw;
assert(utils.equals(s.encode(), new Buffer('51764c', 'hex')));
try {
s.execute(stack);
} catch (e) {
@ -158,6 +160,8 @@ describe('Script', function() {
'OP_1 OP_DUP OP_PUSHDATA2 0x01'
);
assert(utils.equals(s.raw, new Buffer('51764d01', 'hex')));
delete s.raw;
assert(utils.equals(s.encode(), new Buffer('51764d01', 'hex')));
err = null;
try {
s.execute(stack);
@ -170,6 +174,36 @@ describe('Script', function() {
'OP_1 OP_DUP OP_PUSHDATA4 0x0001'
);
assert(utils.equals(s.raw, new Buffer('51764e0001', 'hex')));
delete s.raw;
assert(utils.equals(s.encode(), new Buffer('51764e0001', 'hex')));
err = null;
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
var s = bcoin.script.fromTestString(
'OP_1 OP_DUP OP_PUSHDATA1 0x02 0x01'
);
assert(utils.equals(s.raw, new Buffer('51764c0201', 'hex')));
delete s.raw;
assert(utils.equals(s.encode(), new Buffer('51764c0201', 'hex')));
err = null;
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
var s = bcoin.script.fromTestString(
'OP_1 OP_DUP OP_PUSHDATA2 0x0200 0x01'
);
assert(utils.equals(s.raw, new Buffer('51764d020001', 'hex')));
delete s.raw;
assert(utils.equals(s.encode(), new Buffer('51764d020001', 'hex')));
err = null;
try {
s.execute(stack);