itns-sidechain/test/script-test.js

542 lines
15 KiB
JavaScript
Raw Normal View History

2016-06-13 01:06:01 -07:00
'use strict';
var bcoin = require('../').set('main');
2016-04-29 17:45:13 -07:00
var assert = require('assert');
2016-03-14 19:45:11 -07:00
var Script = bcoin.script;
2016-05-13 10:04:56 -07:00
var Stack = bcoin.stack;
2016-04-19 01:30:12 -07:00
var utils = bcoin.utils;
var constants = bcoin.protocol.constants;
2016-03-28 19:42:05 -07:00
var opcodes = bcoin.protocol.constants.opcodes;
2016-04-19 01:30:12 -07:00
var scripts = require('./data/script_tests');
var bn = require('bn.js');
2014-05-04 23:24:32 +04:00
describe('Script', function() {
it('should encode/decode script', function() {
2016-05-15 21:47:39 -07:00
var src = '20'
+ '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'
+ '20'
+ '101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f'
+ 'ac';
2014-05-04 23:24:32 +04:00
2016-02-22 20:37:15 -08:00
var decoded = bcoin.script.decode(new Buffer(src, 'hex'));
2014-05-04 23:24:32 +04:00
assert.equal(decoded.length, 3);
2016-06-13 21:25:42 -07:00
assert.equal(decoded[0].data.toString('hex'),
2014-05-04 23:24:32 +04:00
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');
2016-06-13 21:25:42 -07:00
assert.equal(decoded[1].data.toString('hex'),
2014-05-04 23:24:32 +04:00
'101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f');
2016-06-13 21:25:42 -07:00
assert.equal(decoded[2].value, opcodes.OP_CHECKSIG);
2014-05-04 23:24:32 +04:00
var dst = bcoin.script.encode(decoded);
2016-04-18 00:36:03 -07:00
assert.equal(dst.toString('hex'), src);
2014-05-04 23:24:32 +04:00
});
2014-05-06 00:55:24 +04:00
it('should encode/decode numbers', function() {
2016-05-15 21:47:39 -07:00
var script = [0, 0x51, 0x52, 0x60];
2016-06-14 16:26:26 -07:00
var encoded = bcoin.script.fromArray(script).raw;
2016-06-13 21:25:42 -07:00
var decoded = bcoin.script.decode(encoded).map(function(op) { return op.value; });
2014-05-06 00:55:24 +04:00
assert.deepEqual(decoded, script);
});
2016-05-15 21:47:39 -07:00
it('should recognize a P2SH output', function() {
var hex = 'a91419a7d869032368fd1f1e26e5e73a4ad0e474960e87';
2016-04-19 11:59:12 -07:00
var decoded = bcoin.script.fromRaw(hex, 'hex');
2016-05-15 21:47:39 -07:00
assert(decoded.isScripthash());
2016-03-14 20:33:15 -07:00
});
2016-05-15 21:47:39 -07:00
it('should recognize a Null Data output', function() {
var hex = '6a28590c080112220a1b353930632e6f7267282a5f'
+ '5e294f7665726c6179404f7261636c65103b1a010c';
2016-04-19 11:59:12 -07:00
var decoded = bcoin.script.fromRaw(hex, 'hex');
2016-05-15 21:47:39 -07:00
assert(decoded.isNulldata());
2016-03-14 20:33:15 -07:00
});
2016-05-15 21:47:39 -07:00
it('should handle if statements correctly', function() {
2016-03-28 19:42:05 -07:00
var inputScript = new Script([opcodes.OP_1, opcodes.OP_2]);
var prevOutScript = new Script([
opcodes.OP_2,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ELSE,
opcodes.OP_4,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-03-14 20:33:15 -07:00
var stack = new Stack();
2016-03-14 19:45:11 -07:00
inputScript.execute(stack);
var res = prevOutScript.execute(stack);
assert(res);
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
2016-03-28 19:42:05 -07:00
var inputScript = new Script([opcodes.OP_1, opcodes.OP_2]);
var prevOutScript = new Script([
opcodes.OP_9,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ELSE,
opcodes.OP_4,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-03-14 20:33:15 -07:00
var stack = new Stack();
2016-03-14 19:45:11 -07:00
inputScript.execute(stack);
var res = prevOutScript.execute(stack);
assert(res);
assert.deepEqual(stack.slice(), [[1], [4], [5]]);
2016-03-28 19:42:05 -07:00
var inputScript = new Script([opcodes.OP_1, opcodes.OP_2]);
var prevOutScript = new Script([
opcodes.OP_2,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-03-14 20:33:15 -07:00
var stack = new Stack();
2016-03-14 19:45:11 -07:00
inputScript.execute(stack);
var res = prevOutScript.execute(stack);
assert(res);
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
2016-03-28 19:42:05 -07:00
var inputScript = new Script([opcodes.OP_1, opcodes.OP_2]);
var prevOutScript = new Script([
opcodes.OP_9,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-03-14 20:33:15 -07:00
var stack = new Stack();
2016-03-14 19:45:11 -07:00
inputScript.execute(stack);
var res = prevOutScript.execute(stack);
assert(res);
assert.deepEqual(stack.slice(), [[1], [5]]);
2016-03-28 19:42:05 -07:00
var inputScript = new Script([opcodes.OP_1, opcodes.OP_2]);
var prevOutScript = new Script([
opcodes.OP_9,
opcodes.OP_EQUAL,
opcodes.OP_NOTIF,
opcodes.OP_3,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-03-14 20:33:15 -07:00
var stack = new Stack();
2016-03-14 19:45:11 -07:00
inputScript.execute(stack);
var res = prevOutScript.execute(stack);
assert(res);
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
2016-03-14 20:33:15 -07:00
});
2016-04-19 01:30:12 -07:00
2016-04-19 04:25:28 -07:00
function success(res, stack) {
if (!res)
return false;
if (stack.length === 0)
return false;
if (!bcoin.script.bool(stack.pop()))
return false;
return true;
}
2016-06-13 21:25:42 -07:00
/*
2016-05-15 21:47:39 -07:00
it('should handle bad size pushes correctly.', function() {
2016-04-20 12:54:32 -07:00
var err;
2016-05-13 10:04:56 -07:00
var stack = new bcoin.stack();
2016-04-20 14:12:40 -07:00
var s = bcoin.script.fromString(
2016-04-20 12:54:32 -07:00
'OP_1 OP_DUP OP_PUSHDATA1'
);
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.raw, new Buffer('51764c', 'hex')));
2016-04-20 13:14:38 -07:00
delete s.raw;
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.encode(), new Buffer('51764c', 'hex')));
2016-04-20 12:54:32 -07:00
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
2016-04-20 14:12:40 -07:00
var s = bcoin.script.fromString(
2016-04-20 12:54:32 -07:00
'OP_1 OP_DUP OP_PUSHDATA2 0x01'
);
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.raw, new Buffer('51764d01', 'hex')));
2016-04-20 13:14:38 -07:00
delete s.raw;
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.encode(), new Buffer('51764d01', 'hex')));
2016-04-20 12:54:32 -07:00
err = null;
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
2016-04-20 14:12:40 -07:00
var s = bcoin.script.fromString(
2016-04-20 12:54:32 -07:00
'OP_1 OP_DUP OP_PUSHDATA4 0x0001'
);
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.raw, new Buffer('51764e0001', 'hex')));
2016-04-20 13:14:38 -07:00
delete s.raw;
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.encode(), new Buffer('51764e0001', 'hex')));
2016-04-20 13:14:38 -07:00
err = null;
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
2016-04-20 14:12:40 -07:00
var s = bcoin.script.fromString(
2016-04-20 13:14:38 -07:00
'OP_1 OP_DUP OP_PUSHDATA1 0x02 0x01'
);
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.raw, new Buffer('51764c0201', 'hex')));
2016-04-20 13:14:38 -07:00
delete s.raw;
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.encode(), new Buffer('51764c0201', 'hex')));
2016-04-20 13:14:38 -07:00
err = null;
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
2016-04-20 14:12:40 -07:00
var s = bcoin.script.fromString(
2016-04-20 13:14:38 -07:00
'OP_1 OP_DUP OP_PUSHDATA2 0x0200 0x01'
);
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.raw, new Buffer('51764d020001', 'hex')));
2016-04-20 13:14:38 -07:00
delete s.raw;
2016-04-30 16:20:40 -07:00
assert(utils.equal(s.encode(), new Buffer('51764d020001', 'hex')));
2016-04-20 12:54:32 -07:00
err = null;
try {
s.execute(stack);
} catch (e) {
err = e;
}
assert(err);
assert(err.code === 'BAD_OPCODE');
});
2016-06-13 21:25:42 -07:00
*/
2016-04-20 12:54:32 -07:00
2016-05-15 21:47:39 -07:00
it('should handle CScriptNums correctly', function() {
var s = new bcoin.script([
new Buffer([0xff, 0xff, 0xff, 0x7f]),
opcodes.OP_NEGATE,
opcodes.OP_DUP,
opcodes.OP_ADD
2016-04-19 04:25:28 -07:00
]);
2016-05-15 21:47:39 -07:00
var s2 = new bcoin.script([
2016-04-19 04:25:28 -07:00
new Buffer([0xfe, 0xff, 0xff, 0xff, 0x80]),
2016-05-15 21:47:39 -07:00
opcodes.OP_EQUAL
2016-04-19 04:25:28 -07:00
]);
2016-05-13 10:04:56 -07:00
var stack = new bcoin.stack();
2016-04-19 04:25:28 -07:00
assert(s.execute(stack));
assert(success(s2.execute(stack), stack));
});
2016-05-15 21:47:39 -07:00
it('should handle CScriptNums correctly', function() {
var s = new bcoin.script([
opcodes.OP_11,
opcodes.OP_10,
opcodes.OP_1,
opcodes.OP_ADD
2016-04-19 04:25:28 -07:00
]);
2016-05-15 21:47:39 -07:00
var s2 = new bcoin.script([
opcodes.OP_NUMNOTEQUAL,
opcodes.OP_NOT
2016-04-19 04:25:28 -07:00
]);
2016-05-13 10:04:56 -07:00
var stack = new bcoin.stack();
2016-04-19 04:25:28 -07:00
assert(s.execute(stack));
assert(success(s2.execute(stack), stack));
});
2016-05-15 21:47:39 -07:00
it('should handle OP_ROLL correctly', function() {
var s = new bcoin.script([
new Buffer([0x16]),
new Buffer([0x15]),
new Buffer([0x14])
2016-04-19 04:25:28 -07:00
]);
2016-05-15 21:47:39 -07:00
var s2 = new bcoin.script([
opcodes.OP_0,
opcodes.OP_ROLL,
2016-04-19 04:25:28 -07:00
new Buffer([0x14]),
2016-05-15 21:47:39 -07:00
opcodes.OP_EQUALVERIFY,
opcodes.OP_DEPTH,
opcodes.OP_2,
opcodes.OP_EQUAL
2016-04-19 04:25:28 -07:00
]);
2016-05-13 10:04:56 -07:00
var stack = new bcoin.stack();
2016-04-19 04:25:28 -07:00
assert(s.execute(stack));
assert(success(s2.execute(stack), stack));
});
2016-04-19 01:30:12 -07:00
scripts.forEach(function(data) {
// ["Format is: [[wit...]?, scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"],
2016-07-01 06:19:57 -07:00
var witness = Array.isArray(data[0]) ? data.shift() : [];
2016-04-19 01:30:12 -07:00
var input = data[0] ? data[0].trim() : data[0] || '';
var output = data[1] ? data[1].trim() : data[1] || '';
var flags = data[2] ? data[2].trim().split(/,\s*/) : [];
var expected = data[3] || '';
var comments = Array.isArray(data[4]) ? data[4].join('. ') : data[4] || '';
2016-06-09 03:38:31 -07:00
var amount = 0;
2016-04-19 01:30:12 -07:00
if (data.length === 1)
return;
if (!comments)
comments = output.slice(0, 60);
comments += ' (' + expected + ')';
2016-07-01 06:19:57 -07:00
if (witness.length !== 0)
2016-06-09 03:38:31 -07:00
amount = witness.pop() * 100000000;
2016-04-20 14:12:40 -07:00
witness = bcoin.witness.fromString(witness);
input = bcoin.script.fromString(input);
output = bcoin.script.fromString(output);
2016-04-19 01:30:12 -07:00
var flag = 0;
for (var i = 0; i < flags.length; i++) {
flag |= constants.flags['VERIFY_' + flags[i]];
}
flags = flag;
2016-04-19 06:45:10 -07:00
[false, true].forEach(function(nocache) {
var suffix = nocache ? ' without cache' : ' with cache';
2016-05-15 21:47:39 -07:00
it('should handle script test' + suffix + ': ' + comments, function() {
2016-04-19 06:45:10 -07:00
var coin = bcoin.tx({
version: 1,
2016-05-19 00:09:06 -07:00
flag: 1,
2016-04-19 06:45:10 -07:00
inputs: [{
prevout: {
hash: constants.NULL_HASH,
index: 0xffffffff
},
coin: null,
script: [bcoin.script.array(0), bcoin.script.array(0)],
2016-05-13 10:04:56 -07:00
witness: new bcoin.witness(),
2016-04-19 06:45:10 -07:00
sequence: 0xffffffff
}],
outputs: [{
script: output,
2016-06-09 03:38:31 -07:00
value: amount
2016-04-19 06:45:10 -07:00
}],
locktime: 0
});
var tx = bcoin.tx({
version: 1,
2016-05-19 00:09:06 -07:00
flag: 1,
2016-04-19 06:45:10 -07:00
inputs: [{
prevout: {
hash: coin.hash('hex'),
index: 0
},
2016-05-18 05:12:28 -07:00
coin: bcoin.coin.fromTX(coin, 0),
2016-04-19 06:45:10 -07:00
script: input,
witness: witness,
sequence: 0xffffffff
}],
outputs: [{
script: new bcoin.script(),
2016-06-09 03:38:31 -07:00
value: amount
2016-04-19 06:45:10 -07:00
}],
locktime: 0
});
if (nocache) {
2016-06-17 17:52:40 -07:00
tx._raw = null;
tx._size = -1;
tx._witnessSize = -1;
2016-06-17 17:52:40 -07:00
tx._lastWitnessSize = 0;
tx._hash = null;
tx._inputValue = -1;
tx._outputValue = -1;
2016-06-17 17:52:40 -07:00
tx._hashPrevouts = null;
tx._hashSequence = null;
tx._hashOutputs = null;
coin._raw = null;
coin._size = -1;
coin._witnessSize = -1;
2016-06-17 17:52:40 -07:00
coin._lastWitnessSize = 0;
coin._hash = null;
coin._inputValue = -1;
coin._outputValue = -1;
2016-06-17 17:52:40 -07:00
coin._hashPrevouts = null;
coin._hashSequence = null;
coin._hashOutputs = null;
2016-05-16 03:18:46 -07:00
delete input._address;
delete output._address;
2016-04-19 06:45:10 -07:00
}
2016-04-19 22:44:54 -07:00
var err, res;
try {
res = Script.verify(input, witness, output, tx, 0, flags);
} catch (e) {
err = e;
}
if (expected !== 'OK') {
assert(!res);
assert(err);
assert.equal(err.code, expected);
return;
}
2016-04-29 17:45:13 -07:00
utils.assert.ifError(err);
2016-04-19 22:44:54 -07:00
assert(res);
2016-04-19 01:30:12 -07:00
});
});
});
2016-05-15 23:51:18 -07:00
2016-06-13 21:25:42 -07:00
/*
2016-05-15 23:51:18 -07:00
it('should execute FindAndDelete correctly', function() {
var s, d, expect;
function del(s) {
s.mutable = true;
return s;
}
s = bcoin.script.fromString('OP_1 OP_2');
del(s);
d = new bcoin.script();
expect = s.clone();
assert.equal(s.findAndDelete(d.encode()), 0);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromString('OP_1 OP_2 OP_3');
del(s);
d = bcoin.script.fromString('OP_2');
del(d);
expect = bcoin.script.fromString('OP_1 OP_3');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromString('OP_3 OP_1 OP_3 OP_3 OP_4 OP_3');
del(s);
d = bcoin.script.fromString('OP_3');
del(d);
expect = bcoin.script.fromString('OP_1 OP_4');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 4);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0302ff03', 'hex');
del(s);
d = bcoin.script.fromRaw('0302ff03', 'hex');
del(d);
expect = new bcoin.script();
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0302ff030302ff03', 'hex');
del(s);
d = bcoin.script.fromRaw('0302ff03', 'hex');
del(d);
expect = new bcoin.script();
del(expect);
assert.equal(s.findAndDelete(d.encode()), 2);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0302ff030302ff03', 'hex');
del(s);
d = bcoin.script.fromRaw('02', 'hex');
del(d);
expect = s.clone();
del(expect);
//assert.equal(s.findAndDelete(d.encode()), 0);
s.findAndDelete(d.encode());
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0302ff030302ff03', 'hex');
del(s);
d = bcoin.script.fromRaw('ff', 'hex');
del(d);
expect = s.clone();
del(expect);
assert.equal(s.findAndDelete(d.encode()), 0);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0302ff030302ff03', 'hex');
del(s);
d = bcoin.script.fromRaw('03', 'hex');
del(d);
expect = new bcoin.script([new Buffer([0xff, 0x03]), new Buffer([0xff, 0x03])]);
del(expect);
assert.equal(s.findAndDelete(d.encode()), 2);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('02feed5169', 'hex');
del(s);
d = bcoin.script.fromRaw('feed51', 'hex');
del(d);
expect = s.clone();
del(expect);
assert.equal(s.findAndDelete(d.encode()), 0);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('02feed5169', 'hex');
del(s);
d = bcoin.script.fromRaw('02feed51', 'hex');
del(d);
expect = bcoin.script.fromRaw('69', 'hex');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('516902feed5169', 'hex');
del(s);
d = bcoin.script.fromRaw('feed51', 'hex');
del(d);
expect = s.clone();
del(expect);
assert.equal(s.findAndDelete(d.encode()), 0);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('516902feed5169', 'hex');
del(s);
d = bcoin.script.fromRaw('02feed51', 'hex');
del(d);
expect = bcoin.script.fromRaw('516969', 'hex');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromString('OP_0 OP_0 OP_1 OP_1');
del(s);
d = bcoin.script.fromString('OP_0 OP_1');
del(d);
expect = bcoin.script.fromString('OP_0 OP_1');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromString('OP_0 OP_0 OP_1 OP_0 OP_1 OP_1');
del(s);
d = bcoin.script.fromString('OP_0 OP_1');
del(d);
expect = bcoin.script.fromString('OP_0 OP_1');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 2);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0003feed', 'hex');
del(s);
d = bcoin.script.fromRaw('03feed', 'hex');
del(d);
expect = bcoin.script.fromRaw('00', 'hex');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
s = bcoin.script.fromRaw('0003feed', 'hex');
del(s);
d = bcoin.script.fromRaw('00', 'hex');
del(d);
expect = bcoin.script.fromRaw('03feed', 'hex');
del(expect);
assert.equal(s.findAndDelete(d.encode()), 1);
assert.deepEqual(s.encode(), expect.encode());
});
2016-06-13 21:25:42 -07:00
*/
2014-05-04 23:24:32 +04:00
});