some Transaction tests fixed (canonical signatures)
This commit is contained in:
parent
7869308784
commit
b227341c12
|
@ -21,7 +21,8 @@ for (var i in Opcode.map) {
|
|||
var intToBufferSM = Util.intToBufferSM
|
||||
var bufferSMToInt = Util.bufferSMToInt;
|
||||
|
||||
function ScriptInterpreter() {
|
||||
function ScriptInterpreter(opts) {
|
||||
this.opts = opts || {};
|
||||
this.stack = [];
|
||||
this.disableUnsafeOpcodes = true;
|
||||
};
|
||||
|
@ -98,8 +99,7 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType,
|
|||
|
||||
if (exec && Buffer.isBuffer(opcode)) {
|
||||
this.stack.push(opcode);
|
||||
}
|
||||
else if (exec || (OP_IF <= opcode && opcode <= OP_ENDIF))
|
||||
} else if (exec || (OP_IF <= opcode && opcode <= OP_ENDIF))
|
||||
switch (opcode) {
|
||||
case OP_0:
|
||||
this.stack.push(new Buffer([]));
|
||||
|
@ -411,10 +411,13 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType,
|
|||
this.stackPop();
|
||||
this.stackPop();
|
||||
this.stack.push(new Buffer([value ? 1 : 0]));
|
||||
console.log(script.toHumanReadable());
|
||||
if (opcode === OP_EQUALVERIFY) {
|
||||
if (value) {
|
||||
this.stackPop();
|
||||
} else {
|
||||
console.log(v1);
|
||||
console.log(v2);
|
||||
throw new Error("OP_EQUALVERIFY negative");
|
||||
}
|
||||
}
|
||||
|
@ -621,7 +624,7 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType,
|
|||
scriptCode.findAndDelete(sig);
|
||||
|
||||
//
|
||||
isCanonicalSignature(new Buffer(sig));
|
||||
this.isCanonicalSignature(new Buffer(sig));
|
||||
|
||||
// Verify signature
|
||||
checkSig(sig, pubkey, scriptCode, tx, inIndex, hashType, function(e, result) {
|
||||
|
@ -695,8 +698,9 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType,
|
|||
var scriptCode = Script.fromChunks(scriptChunks);
|
||||
|
||||
// Drop the signatures, since a signature can't sign itself
|
||||
var that = this;
|
||||
sigs.forEach(function(sig) {
|
||||
isCanonicalSignature(new Buffer(sig));
|
||||
that.isCanonicalSignature(new Buffer(sig));
|
||||
scriptCode.findAndDelete(sig);
|
||||
});
|
||||
|
||||
|
@ -882,6 +886,7 @@ ScriptInterpreter.prototype.getResult = function getResult() {
|
|||
return castBool(this.stack[this.stack.length - 1]);
|
||||
};
|
||||
|
||||
// Use ScriptInterpreter.verifyFull instead
|
||||
ScriptInterpreter.verify =
|
||||
function verify(scriptSig, scriptPubKey, txTo, n, hashType, callback) {
|
||||
if ("function" !== typeof callback) {
|
||||
|
@ -912,8 +917,8 @@ ScriptInterpreter.verify =
|
|||
return si;
|
||||
};
|
||||
|
||||
function verifyStep4(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, opts, callback, si, siCopy) {
|
||||
ScriptInterpreter.prototype.verifyStep4 = function(scriptSig, scriptPubKey,
|
||||
txTo, nIn, hashType, callback, siCopy) {
|
||||
if (siCopy.stack.length == 0) {
|
||||
callback(null, false);
|
||||
return;
|
||||
|
@ -922,19 +927,19 @@ function verifyStep4(scriptSig, scriptPubKey, txTo, nIn,
|
|||
callback(null, castBool(siCopy.stackBack()));
|
||||
}
|
||||
|
||||
function verifyStep3(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, opts, callback, si, siCopy) {
|
||||
if (si.stack.length == 0) {
|
||||
ScriptInterpreter.prototype.verifyStep3 = function(scriptSig,
|
||||
scriptPubKey, txTo, nIn, hashType, callback, siCopy) {
|
||||
if (this.stack.length == 0) {
|
||||
callback(null, false);
|
||||
return;
|
||||
}
|
||||
if (castBool(si.stackBack()) == false) {
|
||||
if (castBool(this.stackBack()) == false) {
|
||||
callback(null, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// if not P2SH, we're done
|
||||
if (!opts.verifyP2SH || !scriptPubKey.isP2SH()) {
|
||||
if (!this.opts.verifyP2SH || !scriptPubKey.isP2SH()) {
|
||||
callback(null, true);
|
||||
return;
|
||||
}
|
||||
|
@ -949,46 +954,48 @@ function verifyStep3(scriptSig, scriptPubKey, txTo, nIn,
|
|||
|
||||
var subscript = new Script(siCopy.stackPop());
|
||||
|
||||
ok = true;
|
||||
var that = this;
|
||||
siCopy.eval(subscript, txTo, nIn, hashType, function(err) {
|
||||
if (err)
|
||||
callback(err);
|
||||
else
|
||||
verifyStep4(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, opts, callback, si, siCopy);
|
||||
if (err) callback(err);
|
||||
else that.verifyStep4(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, callback, siCopy);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function verifyStep2(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, opts, callback, si, siCopy) {
|
||||
if (opts.verifyP2SH) {
|
||||
si.stack.forEach(function(item) {
|
||||
ScriptInterpreter.prototype.verifyStep2 = function(scriptSig, scriptPubKey,
|
||||
txTo, nIn, hashType, callback, siCopy) {
|
||||
if (this.opts.verifyP2SH) {
|
||||
this.stack.forEach(function(item) {
|
||||
siCopy.stack.push(item);
|
||||
});
|
||||
}
|
||||
|
||||
si.eval(scriptPubKey, txTo, nIn, hashType, function(err) {
|
||||
if (err)
|
||||
callback(err);
|
||||
else
|
||||
verifyStep3(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, opts, callback, si, siCopy);
|
||||
var that = this;
|
||||
this.eval(scriptPubKey, txTo, nIn, hashType, function(err) {
|
||||
if (err) callback(err);
|
||||
else that.verifyStep3(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, callback, siCopy);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ScriptInterpreter.verifyFull =
|
||||
function verifyFull(scriptSig, scriptPubKey, txTo, nIn, hashType,
|
||||
opts, callback) {
|
||||
var si = new ScriptInterpreter();
|
||||
var siCopy = new ScriptInterpreter();
|
||||
var si = new ScriptInterpreter(opts);
|
||||
si.verifyFull(scriptSig, scriptPubKey,
|
||||
txTo, nIn, hashType, callback);
|
||||
};
|
||||
|
||||
si.eval(scriptSig, txTo, nIn, hashType, function(err) {
|
||||
if (err)
|
||||
callback(err);
|
||||
else
|
||||
verifyStep2(scriptSig, scriptPubKey, txTo, nIn,
|
||||
hashType, opts, callback, si, siCopy);
|
||||
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 =
|
||||
|
@ -1019,7 +1026,7 @@ var checkSig = ScriptInterpreter.checkSig =
|
|||
}
|
||||
};
|
||||
|
||||
var isCanonicalSignature = ScriptInterpreter.isCanonicalSignature = function(sig, opts) {
|
||||
ScriptInterpreter.prototype.isCanonicalSignature = function(sig) {
|
||||
// See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
|
||||
// A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
|
||||
// Where R and S are not negative (their first byte has its highest bit not set), and not
|
||||
|
@ -1029,7 +1036,9 @@ var isCanonicalSignature = ScriptInterpreter.isCanonicalSignature = function(sig
|
|||
if (!Buffer.isBuffer(sig))
|
||||
throw new Error("arg should be a Buffer");
|
||||
|
||||
opts = opts || {};
|
||||
// TODO: change to opts.verifyStrictEnc to make the default
|
||||
// behavior not verify, as in bitcoin core
|
||||
if (this.opts.dontVerifyStrictEnc) return true;
|
||||
|
||||
var l = sig.length;
|
||||
if (l < 9) throw new Error("Non-canonical signature: too short");
|
||||
|
@ -1076,7 +1085,7 @@ var isCanonicalSignature = ScriptInterpreter.isCanonicalSignature = function(sig
|
|||
if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80))
|
||||
throw new Error("Non-canonical signature: S value excessively padded");
|
||||
|
||||
if (opts.verifyEvenS) {
|
||||
if (this.opts.verifyEvenS) {
|
||||
if (S[nLenS - 1] & 1)
|
||||
throw new Error("Non-canonical signature: S value odd");
|
||||
}
|
||||
|
|
|
@ -259,10 +259,10 @@ Transaction.prototype.verify = function verify(txCache, blockChain, callback) {
|
|||
}
|
||||
|
||||
return txout;
|
||||
};
|
||||
}
|
||||
|
||||
Step(
|
||||
function verifyInputs() {
|
||||
function verifyInputs(opts) {
|
||||
var group = this.group();
|
||||
|
||||
if (self.isCoinBase()) {
|
||||
|
@ -278,7 +278,7 @@ Transaction.prototype.verify = function verify(txCache, blockChain, callback) {
|
|||
|
||||
outpoints.push(txin.o);
|
||||
|
||||
self.verifyInput(n, txout.getScript(), group());
|
||||
self.verifyInput(n, txout.getScript(), opts, group());
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -351,11 +351,14 @@ Transaction.prototype.verify = function verify(txCache, blockChain, callback) {
|
|||
);
|
||||
};
|
||||
|
||||
Transaction.prototype.verifyInput = function verifyInput(n, scriptPubKey, callback) {
|
||||
return ScriptInterpreter.verify(this.ins[n].getScript(),
|
||||
Transaction.prototype.verifyInput = function verifyInput(n, scriptPubKey, opts, callback) {
|
||||
var valid = ScriptInterpreter.verifyFull(
|
||||
this.ins[n].getScript(),
|
||||
scriptPubKey,
|
||||
this, n, 0,
|
||||
opts,
|
||||
callback);
|
||||
return valid;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,9 +81,10 @@ describe('ScriptInterpreter', function() {
|
|||
isHex = 1;
|
||||
} catch (e) {}
|
||||
|
||||
if (isHex)
|
||||
ScriptInterpreter.isCanonicalSignature.bind(sig).should.
|
||||
throw ();
|
||||
// ignore non-hex strings
|
||||
if (isHex) {
|
||||
ScriptInterpreter.isCanonicalSignature.bind(sig).should.throw();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@ var bitcore = bitcore || require('../bitcore');
|
|||
|
||||
var should = chai.should();
|
||||
|
||||
var TransactionModule = bitcore.Transaction;
|
||||
var Transaction;
|
||||
var Transaction = bitcore.Transaction;
|
||||
var In;
|
||||
var Out;
|
||||
var Script = bitcore.Script;
|
||||
|
@ -40,7 +39,7 @@ function parse_test_transaction(entry) {
|
|||
});
|
||||
|
||||
var raw = new Buffer(entry[1], 'hex');
|
||||
var tx = new TransactionModule();
|
||||
var tx = new Transaction();
|
||||
tx.parse(raw);
|
||||
|
||||
// Sanity check transaction has been parsed correctly
|
||||
|
@ -53,10 +52,6 @@ function parse_test_transaction(entry) {
|
|||
|
||||
describe('Transaction', function() {
|
||||
it('should initialze the main object', function() {
|
||||
should.exist(TransactionModule);
|
||||
});
|
||||
it('should be able to create class', function() {
|
||||
Transaction = TransactionModule;
|
||||
should.exist(Transaction);
|
||||
In = Transaction.In;
|
||||
Out = Transaction.Out;
|
||||
|
@ -105,12 +100,12 @@ describe('Transaction', function() {
|
|||
it('#selectUnspent should check confirmations', function() {
|
||||
var u = Transaction.selectUnspent(testdata.dataUnspent, 0.9);
|
||||
should.not.exist(u);
|
||||
var u = Transaction.selectUnspent(testdata.dataUnspent,0.9,true);
|
||||
u = Transaction.selectUnspent(testdata.dataUnspent, 0.9, true);
|
||||
u.length.should.equal(3);
|
||||
|
||||
var u = Transaction.selectUnspent(testdata.dataUnspent,0.11);
|
||||
u = Transaction.selectUnspent(testdata.dataUnspent, 0.11);
|
||||
u.length.should.equal(2);
|
||||
var u = Transaction.selectUnspent(testdata.dataUnspent,0.111);
|
||||
u = Transaction.selectUnspent(testdata.dataUnspent, 0.111);
|
||||
should.not.exist(u);
|
||||
});
|
||||
|
||||
|
@ -122,7 +117,10 @@ describe('Transaction', function() {
|
|||
|
||||
it('#create should be able to create instance', function() {
|
||||
var utxos = testdata.dataUnspent;
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
|
||||
var ret = Transaction.create(utxos, outs, opts);
|
||||
should.exist(ret.tx);
|
||||
|
@ -144,23 +142,34 @@ describe('Transaction', function() {
|
|||
|
||||
it('#create should fail if not enough inputs ', function() {
|
||||
var utxos = testdata.dataUnspent;
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:80}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 80
|
||||
}];
|
||||
Transaction
|
||||
.create
|
||||
.bind(utxos, outs, opts)
|
||||
.should.throw();
|
||||
.should.
|
||||
throw ();
|
||||
|
||||
var outs2 = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.5}];
|
||||
var outs2 = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.5
|
||||
}];
|
||||
should.exist(Transaction.create(utxos, outs2, opts));
|
||||
|
||||
// do not allow unconfirmed
|
||||
Transaction.create.bind(utxos, outs2).should.throw();
|
||||
Transaction.create.bind(utxos, outs2).should.
|
||||
throw ();
|
||||
});
|
||||
|
||||
|
||||
it('#create should create same output as bitcoind createrawtransaction ', function() {
|
||||
var utxos = testdata.dataUnspent;
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
var ret = Transaction.create(utxos, outs, opts);
|
||||
var tx = ret.tx;
|
||||
|
||||
|
@ -172,8 +181,13 @@ describe('Transaction', function() {
|
|||
it('#create should create same output as bitcoind createrawtransaction wo remainder', function() {
|
||||
var utxos = testdata.dataUnspent;
|
||||
// no remainder
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||
var ret = Transaction.create(utxos, outs, {fee:0.03} );
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
var ret = Transaction.create(utxos, outs, {
|
||||
fee: 0.03
|
||||
});
|
||||
var tx = ret.tx;
|
||||
|
||||
// string output generated from: bitcoind createrawtransaction '[{"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1","vout":1},{"txid":"2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2","vout":0} ]' '{"mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE":0.08}'
|
||||
|
@ -183,14 +197,20 @@ describe('Transaction', function() {
|
|||
|
||||
it('#createAndSign should sign a tx', function() {
|
||||
var utxos = testdata.dataUnspentSign.unspent;
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
var ret = Transaction.createAndSign(utxos, outs, testdata.dataUnspentSign.keyStrings, opts);
|
||||
var tx = ret.tx;
|
||||
tx.isComplete().should.equal(true);
|
||||
tx.ins.length.should.equal(1);
|
||||
tx.outs.length.should.equal(2);
|
||||
|
||||
var outs2 = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:16}];
|
||||
var outs2 = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 16
|
||||
}];
|
||||
var ret2 = Transaction.createAndSign(utxos, outs2, testdata.dataUnspentSign.keyStrings, opts);
|
||||
var tx2 = ret2.tx;
|
||||
tx2.isComplete().should.equal(true);
|
||||
|
@ -201,7 +221,10 @@ describe('Transaction', function() {
|
|||
it('#createAndSign should sign an incomplete tx ', function() {
|
||||
var keys = ['cNpW8B7XPAzCdRR9RBWxZeveSNy3meXgHD8GuhcqUyDuy8ptCDzJ'];
|
||||
var utxos = testdata.dataUnspentSign.unspent;
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
var ret = Transaction.createAndSign(utxos, outs, keys, opts);
|
||||
var tx = ret.tx;
|
||||
tx.ins.length.should.equal(1);
|
||||
|
@ -210,7 +233,10 @@ describe('Transaction', function() {
|
|||
it('#isComplete should return TX signature status', function() {
|
||||
var keys = ['cNpW8B7XPAzCdRR9RBWxZeveSNy3meXgHD8GuhcqUyDuy8ptCDzJ'];
|
||||
var utxos = testdata.dataUnspentSign.unspent;
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
var ret = Transaction.createAndSign(utxos, outs, keys, opts);
|
||||
var tx = ret.tx;
|
||||
tx.isComplete().should.equal(false);
|
||||
|
@ -219,7 +245,10 @@ describe('Transaction', function() {
|
|||
});
|
||||
|
||||
it('#sign should sign a tx in multiple steps (case1)', function() {
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:1.08}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 1.08
|
||||
}];
|
||||
var ret = Transaction.create(testdata.dataUnspentSign.unspent, outs, opts);
|
||||
var tx = ret.tx;
|
||||
var selectedUtxos = ret.selectedUtxos;
|
||||
|
@ -236,7 +265,10 @@ describe('Transaction', function() {
|
|||
});
|
||||
|
||||
it('#sign should sign a tx in multiple steps (case2)', function() {
|
||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:16}];
|
||||
var outs = [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 16
|
||||
}];
|
||||
var ret = Transaction.create(testdata.dataUnspentSign.unspent, outs, opts);
|
||||
var tx = ret.tx;
|
||||
var selectedUtxos = ret.selectedUtxos;
|
||||
|
@ -257,7 +289,10 @@ describe('Transaction', function() {
|
|||
var outs = [];
|
||||
var n = 101;
|
||||
for (var i = 0; i < n; i++) {
|
||||
outs.push({address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.01});
|
||||
outs.push({
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.01
|
||||
});
|
||||
}
|
||||
|
||||
var ret = Transaction.createAndSign(utxos, outs, testdata.dataUnspentSign.keyStrings, opts);
|
||||
|
@ -275,15 +310,18 @@ describe('Transaction', function() {
|
|||
|
||||
|
||||
//this is the complementary case, it does not trigger a new utxo
|
||||
var utxos =testdata.dataUnspentSign.unspent;
|
||||
var outs = [];
|
||||
var n =100;
|
||||
for (var i=0; i<n; i++) {
|
||||
outs.push({address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.01});
|
||||
utxos = testdata.dataUnspentSign.unspent;
|
||||
outs = [];
|
||||
n = 100;
|
||||
for (i = 0; i < n; i++) {
|
||||
outs.push({
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.01
|
||||
});
|
||||
}
|
||||
|
||||
var ret = Transaction.createAndSign(utxos, outs, testdata.dataUnspentSign.keyStrings, opts);
|
||||
var tx = ret.tx;
|
||||
ret = Transaction.createAndSign(utxos, outs, testdata.dataUnspentSign.keyStrings, opts);
|
||||
tx = ret.tx;
|
||||
tx.getSize().should.equal(3485);
|
||||
|
||||
// ins = 1.0101 BTC (1 inputs: 1.0101);
|
||||
|
@ -297,21 +335,30 @@ describe('Transaction', function() {
|
|||
});
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Bitcoin core transaction tests
|
||||
*/
|
||||
// Verify that known valid transactions are intepretted correctly
|
||||
testdata.dataTxValid.forEach(function(datum) {
|
||||
var testTx = parse_test_transaction(datum);
|
||||
if (!testTx) return;
|
||||
var verifyP2SH = datum[2];
|
||||
var transactionString = buffertools.toHex(
|
||||
testTx.transaction.serialize());
|
||||
|
||||
it.skip('valid tx=' + transactionString, function() {
|
||||
it('valid tx=' + transactionString, function() {
|
||||
// Verify that all inputs are valid
|
||||
testTx.inputs.forEach(function(input) {
|
||||
testTx.transaction.verifyInput(input.index, input.scriptPubKey,
|
||||
testTx.transaction.verifyInput(
|
||||
input.index,
|
||||
input.scriptPubKey,
|
||||
{ verifyP2SH: verifyP2SH, dontVerifyStrictEnc: true},
|
||||
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;
|
||||
if (err && err.constructor.name === 'AssertionError') return;
|
||||
|
||||
should.not.exist(err);
|
||||
should.exist(results);
|
||||
|
@ -328,14 +375,14 @@ describe('Transaction', function() {
|
|||
var transactionString = buffertools.toHex(
|
||||
testTx.transaction.serialize());
|
||||
|
||||
it.skip('valid tx=' + transactionString, function() {
|
||||
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;
|
||||
if (err && err.constructor.name === 'AssertionError') return;
|
||||
|
||||
// There should either be an error, or the results should be false.
|
||||
(err !== null || (!err && results === false)).should.equal(true);
|
||||
|
|
|
@ -15,8 +15,8 @@ var examples = [
|
|||
];
|
||||
|
||||
describe('Examples', function() {
|
||||
before(mute);
|
||||
after(unmute);
|
||||
//before(mute);
|
||||
//after(unmute);
|
||||
examples.forEach(function(example) {
|
||||
it('valid '+example, function() {
|
||||
var ex = require('../examples/'+example);
|
||||
|
|
Loading…
Reference in New Issue