From 72d9a9377344ea923084871fb2ab8bb4342400d1 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 9 Dec 2015 14:35:23 -0800 Subject: [PATCH] fix and test if statements. fix comparisons. --- lib/bcoin/script.js | 35 ++++++++++++++++++----------------- test/script-test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 1eb33d58..e8c45f58 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -136,7 +136,7 @@ script._next = function(to, s, pc) { var o = s[pc]; if (o === 'if_' || o === 'notif') depth++; - else if (o === 'else') + else if (o === 'else_') depth--; else if (o === 'endif') depth--; @@ -144,7 +144,7 @@ script._next = function(to, s, pc) { break; if (depth === 0 && o === to) return pc; - if (o === 'else') + if (o === 'else_') depth++; pc++; } @@ -157,7 +157,6 @@ script.execute = function execute(s, stack, tx, index) { if (s.length > 10000) return false; - var input = tx.inputs[index]; var lastSep = -1; stack.alt = stack.alt || []; @@ -193,7 +192,7 @@ script.execute = function execute(s, stack, tx, index) { if (stack.length < 1) return false; var v = stack.pop(); - val = new bn(v).cmp(0) !== 0; + val = new bn(v).cmpn(0) !== 0; if (o === 'notif') val = !val; var if_ = pc; @@ -213,10 +212,12 @@ script.execute = function execute(s, stack, tx, index) { } else { if (endif === -1) return false; - if (else_ === -1) + if (else_ === -1) { s.splice(if_, (endif - if_) + 1); - else + } else { + s.splice(endif, 1); s.splice(if_, (else_ - if_) + 1); + } } // Subtract one since we removed the if/notif opcode pc--; @@ -231,7 +232,7 @@ script.execute = function execute(s, stack, tx, index) { case 'verify': { if (stack.length === 0) return false; - if (new bn(stack[stack.length - 1]).cmp(0) === 0) + if (new bn(stack[stack.length - 1]).cmpn(0) === 0) return false; break; } @@ -253,7 +254,7 @@ script.execute = function execute(s, stack, tx, index) { case 'ifdup': { if (stack.length === 0) return false; - if (new bn(stack[stack.length - 1]).cmp(0) !== 0) + if (new bn(stack[stack.length - 1]).cmpn(0) !== 0) stack.push(new bn(stack[stack.length - 1]).toArray()); break; } @@ -411,14 +412,14 @@ script.execute = function execute(s, stack, tx, index) { n = n.neg(); break; case 'abs': - if (n.cmp(0) < 0) + if (n.cmpn(0) < 0) n = n.neg(); break; case 'not': - n = n.cmp(0) === 0; + n = n.cmpn(0) === 0; break; case 'noteq0': - n = n.cmp(0) !== 0; + n = n.cmpn(0) !== 0; break; default: return false; @@ -466,10 +467,10 @@ script.execute = function execute(s, stack, tx, index) { n = n1.sub(n2); break; case 'booland': - n = n1.cmp(0) !== 0 && n2.cmp(0) !== 0; + n = n1.cmpn(0) !== 0 && n2.cmpn(0) !== 0; break; case 'boolor': - n = n1.cmp(0) !== 0 || n2.cmp(0) !== 0; + n = n1.cmpn(0) !== 0 || n2.cmpn(0) !== 0; break; case 'numeq': n = n1.cmp(n2) === 0; @@ -501,7 +502,7 @@ script.execute = function execute(s, stack, tx, index) { default: return false; } - var res = n.cmp(0) !== 0; + var res = n.cmpn(0) !== 0; if (o === 'numeqverify') { if (!res) return false; @@ -517,7 +518,7 @@ script.execute = function execute(s, stack, tx, index) { var n2 = new bn(stack.pop()); var n1 = new bn(stack.pop()); var val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0; - stack.push(val.cmp(0) !== 0 ? [ 1 ] : []); + stack.push(val.cmpn(0) !== 0 ? [ 1 ] : []); break; } @@ -665,7 +666,7 @@ script.execute = function execute(s, stack, tx, index) { // input: [[], sig1, sig2, 1] // prev_out: [[lock], 'checklocktimeverify', 'drop', // 'dup', 'hash160', pubkey, 'equalverify', 'checksig'] - if (stack.length === 0) + if (!tx || stack.length === 0) return false; var lock = new bn(stack[stack.length - 1]).toNumber(); @@ -684,7 +685,7 @@ script.execute = function execute(s, stack, tx, index) { if (lock > tx.lock) return false; - if (input.seq === 0xffffffff) + if (!tx.inputs[index] || tx.inputs[index].seq === 0xffffffff) return false; break; diff --git a/test/script-test.js b/test/script-test.js index 3b5e24ea..e3a91f8e 100644 --- a/test/script-test.js +++ b/test/script-test.js @@ -44,4 +44,46 @@ describe('Script', function() { var decoded = bcoin.script.decode(encoded); assert(bcoin.script.isNullData(decoded)) }) + + it('should handle if statements correctly', function () { + var inputScript = [1, 2]; + var prevOutScript = [2, 'eq', 'if_', 3, 'else_', 4, 'endif', 5]; + var stack = []; + bcoin.script.execute(inputScript, stack); + var res = bcoin.script.execute(prevOutScript, stack); + assert(res); + assert.deepEqual(stack.slice(), [[1], [3], [5]]); + + var inputScript = [1, 2]; + var prevOutScript = [9, 'eq', 'if_', 3, 'else_', 4, 'endif', 5]; + var stack = []; + bcoin.script.execute(inputScript, stack); + var res = bcoin.script.execute(prevOutScript, stack); + assert(res); + assert.deepEqual(stack.slice(), [[1], [4], [5]]); + + var inputScript = [1, 2]; + var prevOutScript = [2, 'eq', 'if_', 3, 'endif', 5]; + var stack = []; + bcoin.script.execute(inputScript, stack); + var res = bcoin.script.execute(prevOutScript, stack); + assert(res); + assert.deepEqual(stack.slice(), [[1], [3], [5]]); + + var inputScript = [1, 2]; + var prevOutScript = [9, 'eq', 'if_', 3, 'endif', 5]; + var stack = []; + bcoin.script.execute(inputScript, stack); + var res = bcoin.script.execute(prevOutScript, stack); + assert(res); + assert.deepEqual(stack.slice(), [[1], [5]]); + + var inputScript = [1, 2]; + var prevOutScript = [9, 'eq', 'notif', 3, 'endif', 5]; + var stack = []; + bcoin.script.execute(inputScript, stack); + var res = bcoin.script.execute(prevOutScript, stack); + assert(res); + assert.deepEqual(stack.slice(), [[1], [3], [5]]); + }) });