test. fix sigops counting.
This commit is contained in:
parent
11ef30b942
commit
c1fd8bb285
@ -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}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user