tracking Transaction test problems

This commit is contained in:
Manuel Araoz 2014-03-26 18:04:29 -03:00
parent 0fd1848eb4
commit 499b171947
2 changed files with 79 additions and 53 deletions

View File

@ -33,6 +33,7 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType,
throw new Error("ScriptInterpreter.eval() requires a callback");
}
console.log('eval script '+script.toHumanReadable());
var pc = 0;
var execStack = [];
var altStack = [];
@ -718,6 +719,7 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType,
// If there are more signatures than keys left, then too many
// signatures have failed
if (sigsCount > keysCount) {
console.log('CHECKMULTISIG sigsCount > keysCount');
success = false;
}
}
@ -866,7 +868,7 @@ ScriptInterpreter.prototype.getResult = function getResult() {
return castBool(this.stack[this.stack.length - 1]);
};
// Use ScriptInterpreter.verifyFull instead
// WARN: Use ScriptInterpreter.verifyFull instead
ScriptInterpreter.verify =
function verify(scriptSig, scriptPubKey, txTo, n, hashType, callback) {
if ("function" !== typeof callback) {
@ -892,8 +894,8 @@ ScriptInterpreter.verify =
return si;
};
ScriptInterpreter.prototype.verifyStep4 = function(scriptSig, scriptPubKey,
txTo, nIn, hashType, callback, siCopy) {
ScriptInterpreter.prototype.verifyStep4 = function(callback, siCopy) {
// 4th step, check P2SH subscript evaluated to true
if (siCopy.stack.length == 0) {
callback(null, false);
return;
@ -904,55 +906,85 @@ ScriptInterpreter.prototype.verifyStep4 = function(scriptSig, scriptPubKey,
ScriptInterpreter.prototype.verifyStep3 = function(scriptSig,
scriptPubKey, txTo, nIn, hashType, callback, siCopy) {
if (this.stack.length == 0) {
callback(null, false);
return;
}
if (castBool(this.stackBack()) == false) {
// 3rd step, check result (stack should contain true)
// if stack is empty, script considered invalid
if (this.stack.length === 0) {
console.log('3rd step: no stack');
callback(null, false);
return;
}
// if not P2SH, we're done
// if top of stack contains false, script evaluated to false
if (castBool(this.stackBack()) == false) {
console.log('3rd step: stack contains false');
callback(null, false);
return;
}
// if not P2SH, script evaluated to true
if (!this.opts.verifyP2SH || !scriptPubKey.isP2SH()) {
console.log('3rd step: done, true');
callback(null, true);
return;
}
// if P2SH, scriptSig should be push-only
if (!scriptSig.isPushOnly()) {
console.log('3rd step: scriptSig should be push only');
callback(null, false);
return;
}
if (siCopy.length === 0)
throw new Error('siCopy should have length != 0');
// P2SH script should exist
if (siCopy.length === 0) {
throw new Error('siCopy should have length != 0');
}
var subscript = new Script(siCopy.stackPop());
var that = this;
// evaluate the P2SH subscript
siCopy.eval(subscript, txTo, nIn, hashType, function(err) {
if (err) callback(err);
else that.verifyStep4(scriptSig, scriptPubKey, txTo, nIn,
hashType, callback, siCopy);
console.log('Err 3nd step: '+err);
if (err) return callback(err);
that.verifyStep4(callback, siCopy);
});
};
ScriptInterpreter.prototype.verifyStep2 = function(scriptSig, scriptPubKey,
txTo, nIn, hashType, callback, siCopy) {
var siCopy;
if (this.opts.verifyP2SH) {
siCopy = new ScriptInterpreter(this.opts);
this.stack.forEach(function(item) {
siCopy.stack.push(item);
});
}
var that = this;
// 2nd step, evaluate scriptPubKey
this.eval(scriptPubKey, txTo, nIn, hashType, function(err) {
if (err) callback(err);
else that.verifyStep3(scriptSig, scriptPubKey, txTo, nIn,
console.log('Err 2nd step: '+err);
if (err) return callback(err);
that.verifyStep3(scriptSig, scriptPubKey, txTo, nIn,
hashType, callback, siCopy);
});
};
ScriptInterpreter.prototype.verifyFull = function(scriptSig, scriptPubKey,
txTo, nIn, hashType, callback) {
var that = this;
// 1st step, evaluate scriptSig
this.eval(scriptSig, txTo, nIn, hashType, function(err) {
console.log('Err 1st step: '+err);
if (err) return callback(err);
that.verifyStep2(scriptSig, scriptPubKey, txTo, nIn,
hashType, callback);
});
};
ScriptInterpreter.verifyFull =
function verifyFull(scriptSig, scriptPubKey, txTo, nIn, hashType,
opts, callback) {
@ -961,19 +993,6 @@ ScriptInterpreter.verifyFull =
txTo, nIn, hashType, callback);
};
ScriptInterpreter.prototype.verifyFull = function(scriptSig, scriptPubKey,
txTo, nIn, hashType, callback) {
var siCopy = new ScriptInterpreter(this.opts);
var that = this;
this.eval(scriptSig, txTo, nIn, hashType, function(err) {
if (err) callback(err);
else {
that.verifyStep2(scriptSig, scriptPubKey, txTo, nIn,
hashType, callback, siCopy);
}
});
};
var checkSig = ScriptInterpreter.checkSig =
function(sig, pubkey, scriptCode, tx, n, hashType, callback) {

View File

@ -72,32 +72,39 @@ describe('Transaction', function() {
var raw = datum[1];
var verifyP2SH = datum[2];
it.skip((valid ? '' : 'in') + 'valid tx=' + raw, function(done) {
var cb = function(err, results) {
should.not.exist(err);
should.exist(results);
results.should.equal(valid);
done();
};
describe((valid ? '' : 'in') + 'valid tx=' + raw, function() {
var testTx = parse_test_transaction(datum);
buffertools.toHex(testTx.transaction.serialize()).should.equal(raw);
it('should parse correctly', function() {
buffertools.toHex(testTx.transaction.serialize()).should.equal(raw);
});
var inputs = testTx.transaction.inputs();
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
buffertools.reverse(input[0]);
input[0] = buffertools.toHex(input[0]);
var mapKey = [input];
var scriptPubKey = testTx.inputs[mapKey];
if (!scriptPubKey) throw new Error('Bad test: '+datum);
testTx.transaction.verifyInput(
i,
scriptPubKey, {
verifyP2SH: verifyP2SH,
dontVerifyStrictEnc: true
},
cb);
}
var j = 0;
inputs.forEach(function(input) {
var i = j;
j += 1;
it('should validate input #' + i, function(done) {
buffertools.reverse(input[0]);
input[0] = buffertools.toHex(input[0]);
var mapKey = [input];
var scriptPubKey = testTx.inputs[mapKey];
if (!scriptPubKey) throw new Error('Bad test: ' + datum);
testTx.transaction.verifyInput(
i,
scriptPubKey, {
verifyP2SH: verifyP2SH,
dontVerifyStrictEnc: true
},
function(err, results) {
should.not.exist(err);
should.exist(results);
results.should.equal(valid);
done();
}
);
});
});
});
});
};