|
|
@ -15,6 +15,44 @@ var util = bitcore.util; |
|
|
|
var buffertools = require('buffertools'); |
|
|
|
var testdata = testdata || require('./testdata'); |
|
|
|
|
|
|
|
// Read tests from test/data/tx_valid.json and tx_invalid.json
|
|
|
|
// Format is an array of arrays
|
|
|
|
// Inner arrays are either [ "comment" ]
|
|
|
|
// or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH
|
|
|
|
// ... where all scripts are stringified scripts.
|
|
|
|
// Returns an object with the Transaction object, and an array of input objects
|
|
|
|
function parse_test_transaction(entry) { |
|
|
|
// Ignore comments
|
|
|
|
if (entry.length !== 3) return; |
|
|
|
|
|
|
|
var inputs = []; |
|
|
|
entry[0].forEach(function(vin) { |
|
|
|
var hash = vin[0]; |
|
|
|
var index = vin[1]; |
|
|
|
var scriptPubKey = Script.fromHumanReadable(vin[2]); |
|
|
|
|
|
|
|
inputs.push({ |
|
|
|
'prev_tx_hash': hash, |
|
|
|
'index': index, |
|
|
|
'scriptPubKey': scriptPubKey |
|
|
|
}); |
|
|
|
|
|
|
|
console.log(scriptPubKey.toHumanReadable()); |
|
|
|
console.log('********************************'); |
|
|
|
}); |
|
|
|
|
|
|
|
var raw = new Buffer(entry[1], 'hex'); |
|
|
|
var tx = new TransactionModule(); |
|
|
|
tx.parse(raw); |
|
|
|
|
|
|
|
// Sanity check transaction has been parsed correctly
|
|
|
|
buffertools.toHex(tx.serialize()).should.equal(buffertools.toHex(raw)); |
|
|
|
return { |
|
|
|
'transaction': tx, |
|
|
|
'inputs': inputs |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
describe('Transaction', function() { |
|
|
|
it('should initialze the main object', function() { |
|
|
|
should.exist(TransactionModule); |
|
|
@ -261,60 +299,49 @@ describe('Transaction', function() { |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Read tests from test/data/tx_valid.json
|
|
|
|
// Format is an array of arrays
|
|
|
|
// Inner arrays are either [ "comment" ]
|
|
|
|
// or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH
|
|
|
|
// ... where all scripts are stringified scripts.
|
|
|
|
// Verify that known valid transactions are intepretted correctly
|
|
|
|
testdata.dataTxValid.forEach(function(datum) { |
|
|
|
if (datum.length === 3) { |
|
|
|
it('valid tx=' + datum[1], function() { |
|
|
|
var inputs = datum[0]; |
|
|
|
var inputScriptPubKeys = []; |
|
|
|
inputs.forEach(function(vin) { |
|
|
|
var hash = vin[0]; |
|
|
|
var index = vin[1]; |
|
|
|
debugger; |
|
|
|
var scriptPubKey = Script.fromHumanReadable(vin[2]); |
|
|
|
inputScriptPubKeys.push(scriptPubKey); |
|
|
|
console.log(scriptPubKey.toHumanReadable()); |
|
|
|
console.log('********************************'); |
|
|
|
done(); |
|
|
|
|
|
|
|
}); |
|
|
|
var raw = new Buffer(datum[1], 'hex'); |
|
|
|
var tx = new Transaction(); |
|
|
|
tx.parse(raw); |
|
|
|
|
|
|
|
buffertools.toHex(tx.serialize()).should.equal(buffertools.toHex(raw)); |
|
|
|
|
|
|
|
var n = 0; |
|
|
|
inputScriptPubKeys.forEach(function(scriptPubKey) { |
|
|
|
var err = undefined; |
|
|
|
var results = undefined; |
|
|
|
var inputVerified = false; |
|
|
|
|
|
|
|
tx.verifyInput(n, scriptPubKey, function(e, r) { |
|
|
|
var testTx = parse_test_transaction(datum); |
|
|
|
if (!testTx) return; |
|
|
|
var transactionString = buffertools.toHex( |
|
|
|
testTx.transaction.serialize()); |
|
|
|
|
|
|
|
it('valid tx=' + transactionString, function() { |
|
|
|
// Verify that all inputs are valid
|
|
|
|
testTx.inputs.forEach(function(input) { |
|
|
|
testTx.transaction.verifyInput(input.index, input.scriptPubKey, |
|
|
|
function(err, results) { |
|
|
|
// Exceptions raised inside this function will be handled
|
|
|
|
// ...by this function, so don't do it.
|
|
|
|
err = e; |
|
|
|
results = r; |
|
|
|
inputVerified = true; |
|
|
|
}); |
|
|
|
|
|
|
|
// TODO(mattfaus): Add a Promise or something that makes this code
|
|
|
|
// execute only after the verifyInput() callback has finished
|
|
|
|
while (!inputVerified) { } |
|
|
|
// ...by this function, so ignore if that is the case
|
|
|
|
if (err && err.constructor.name === "AssertionError") return; |
|
|
|
|
|
|
|
should.not.exist(err); |
|
|
|
should.exist(results); |
|
|
|
results.should.equal(true); |
|
|
|
should.not.exist(err); |
|
|
|
should.exist(results); |
|
|
|
results.should.equal(true); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
n += 1; |
|
|
|
}); |
|
|
|
// Verify that known invalid transactions are interpretted correctly
|
|
|
|
test_data.dataTxInvalid.forEach(function(datum) { |
|
|
|
var testTx = parse_test_transaction(datum); |
|
|
|
if (!testTx) return; |
|
|
|
var transactionString = buffertools.toHex( |
|
|
|
testTx.transaction.serialize()); |
|
|
|
|
|
|
|
it('valid tx=' + transactionString, function() { |
|
|
|
// Verify that all inputs are invalid
|
|
|
|
testTx.inputs.forEach(function(input) { |
|
|
|
testTx.transaction.verifyInput(input.index, input.scriptPubKey, |
|
|
|
function(err, results) { |
|
|
|
// Exceptions raised inside this function will be handled
|
|
|
|
// ...by this function, so ignore if that is the case
|
|
|
|
if (err && err.constructor.name === "AssertionError") return; |
|
|
|
|
|
|
|
// TODO(mattfaus): Other verifications?
|
|
|
|
should.exist(err); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|