diff --git a/js/models/core/TxProposal.js b/js/models/core/TxProposal.js index 68d786311..6842a2449 100644 --- a/js/models/core/TxProposal.js +++ b/js/models/core/TxProposal.js @@ -32,7 +32,7 @@ function TxProposal(opts) { this.sentTxid = opts.sentTxid || null; this.comment = opts.comment || null; this.readonly = opts.readonly || null; - this._updateSignedBy(); + // this._updateSignedBy(); } TxProposal.prototype.getId = function() { @@ -84,33 +84,37 @@ TxProposal.prototype._formatKeys = function(allowedPubKeys) { var k = new Key(); k.public = allowedPubKeys[i]; - keys.push[k]; + keys.push(k); }; + + return keys; }; TxProposal.prototype._verifySignatures = function(inKeys, scriptSig, txSigHash) { preconditions.checkArgument(Buffer.isBuffer(txSigHash)); + preconditions.checkArgument(inKeys); + preconditions.checkState(Buffer.isBuffer(inKeys[0])); if (scriptSig.chunks[0] !== 0) throw new Error('Invalid scriptSig'); - var keys = this._formatKeys(inKeys); var ret = []; - for (var i = 1; typeof ret === 'undefined' && i <= scriptSig.countSignatures(); i++) { + for (var i = 1; i <= scriptSig.countSignatures(); i++) { var chunk = scriptSig.chunks[i]; var sigRaw = new Buffer(chunk.slice(0, chunk.length - 1)); for (var j in keys) { var k = keys[j]; if (k.verifySignatureSync(txSigHash, sigRaw)) { - ret.push(j); - } + ret.push(parseInt(j)); + break; + } } } return ret; }; TxProposal.prototype._keysFromRedeemScript = function(s) { - var redeemScript = new Script(s.chunks[s.chunks.length-1]); + var redeemScript = new Script(s.chunks[s.chunks.length - 1]); if (!redeemScript) throw new Error('Bad scriptSig'); var pubkeys = redeemScript.capture(); diff --git a/test/test.TxProposal.js b/test/test.TxProposal.js index fc7d1f8fe..2fcaccc18 100644 --- a/test/test.TxProposal.js +++ b/test/test.TxProposal.js @@ -29,7 +29,7 @@ var dummyProposal = new TxProposal({ inputChainPaths: ['m/1'], }); -var someKeys = ["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"]; +var someKeys = ["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5", "022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"]; describe('TxProposal', function() { describe('new', function() { @@ -63,7 +63,7 @@ describe('TxProposal', function() { }); }); describe('#getId', function() { - it('should return id',function() { + it('should return id', function() { var b = new FakeBuilder(); var spy = sinon.spy(b.tx, 'getNormalizedHash'); var txp = new TxProposal({ @@ -73,11 +73,11 @@ describe('TxProposal', function() { inputChainPaths: 'm/1', }); txp.getId().should.equal('123456');; - sinon.assert.callCount(spy,1); + sinon.assert.callCount(spy, 1); }); }); describe('#toObj', function() { - it('should return an object and remove builder',function() { + it('should return an object and remove builder', function() { var b = new FakeBuilder(); var txp = new TxProposal({ creator: 1, @@ -93,33 +93,35 @@ describe('TxProposal', function() { }); }); describe('#fromObj', function() { - it.skip('should create from Object',function() { + it.skip('should create from Object', function() { var b = new FakeBuilder(); var txp = TxProposal.fromObj({ creator: 1, createdTs: 1, builderObj: b.toObj(), - inputChainPaths: ['m/1'] , + inputChainPaths: ['m/1'], }); should.exist(txp); }); - it('should fail to create from wrong object',function() { + it('should fail to create from wrong object', function() { var b = new FakeBuilder(); - (function(){var txp = TxProposal.fromObj({ - creator: 1, - createdTs: 1, - builderObj: b.toObj(), - inputChainPaths: ['m/1'] , - });}).should.throw('Invalid'); + (function() { + var txp = TxProposal.fromObj({ + creator: 1, + createdTs: 1, + builderObj: b.toObj(), + inputChainPaths: ['m/1'], + }); + }).should.throw('Invalid'); }); }); describe('#setSent', function() { - it('should set txid and timestamp',function() { + it('should set txid and timestamp', function() { var now = Date.now(); var txp = dummyProposal; txp.setSent('3a42'); @@ -132,38 +134,47 @@ describe('TxProposal', function() { describe('Signature verification', function() { var validScriptSig = '00483045022100a35a5cbe37e39caa62bf1c347eae9c72be827c190b31494b184943b3012757a8022008a1ff72a34a5bf2fc955aa5b6f8a4c32cb0fab7e54c212a5f6f645bb95b8ef10149304602210092347916c3c3e6f1692bf9447b973779c28ce9985baaa3940b483af573f464b4022100ab91062796ab8acb32a0fa90e00627db5be77d9722400b3ecfd9c5f34a8092b1014cad532103197599f6e209cefef07da2fddc6fe47715a70162c531ffff8e611cef23dfb70d210380a29968851f93af55e581c43d9ef9294577a439a3ca9fc2bc47d1ca2b3e9127210392dccb2ed470a45984811d6402fdca613c175f8f3e4eb8e2306e8ccd7d0aed032103a94351fecc4328bb683bf93a1aa67378374904eac5980c7966723a51897c56e32103e085eb6fa1f20b2722c16161144314070a2c316a9cae2489fd52ce5f63fff6e455ae'; - var keyBuf = someKeys.map(function(hex){ - return new Buffer(hex,'hex'); + var pubkeys = [ + '03197599f6e209cefef07da2fddc6fe47715a70162c531ffff8e611cef23dfb70d', + '0380a29968851f93af55e581c43d9ef9294577a439a3ca9fc2bc47d1ca2b3e9127', + '0392dccb2ed470a45984811d6402fdca613c175f8f3e4eb8e2306e8ccd7d0aed03', + '03a94351fecc4328bb683bf93a1aa67378374904eac5980c7966723a51897c56e3', + '03e085eb6fa1f20b2722c16161144314070a2c316a9cae2489fd52ce5f63fff6e4' + ].map(function(hex) { + return new Buffer(hex, 'hex'); }); - it('#_formatKeys',function() { + var keyBuf = someKeys.map(function(hex) { + return new Buffer(hex, 'hex'); + }); + it('#_formatKeys', function() { var txp = dummyProposal; - (function(){txp._formatKeys(someKeys);}).should.throw('buffers'); + (function() { + txp._formatKeys(someKeys); + }).should.throw('buffers'); var res = txp._formatKeys(keyBuf); }); - it('#_verifyScriptSig arg checks',function() { + it('#_verifyScriptSig arg checks', function() { var txp = dummyProposal; - ( function() { txp._verifySignatures( - keyBuf, - new bitcore.Script(new Buffer('112233','hex')), - new Buffer('1a','hex')); } ).should.throw('script'); + (function() { + txp._verifySignatures( + keyBuf, + new bitcore.Script(new Buffer('112233', 'hex')), + new Buffer('1a', 'hex')); + }).should.throw('script'); }); - it('#_verifyScriptSig, no signatures',function() { + it('#_verifyScriptSig, no signatures', function() { var txp = dummyProposal; - var ret = txp._verifySignatures( - keyBuf, - new bitcore.Script(new Buffer(validScriptSig,'hex')), - new Buffer('1a','hex') - ); + var ret = txp._verifySignatures( keyBuf, new bitcore.Script(new Buffer(validScriptSig, 'hex')), new Buffer(32)); ret.length.should.equal(0); }); - it('#_verifyScriptSig, one signature',function() { + it('#_verifyScriptSig, one signature', function() { + // Data taken from bitcore's TransactionBuilder test var txp = dummyProposal; - var ret = txp._verifySignatures( - [new Buffer('0380a29968851f93af55e581c43d9ef9294577a439a3ca9fc2bc47d1ca2b3e9127','hex')], - new bitcore.Script(new Buffer(validScriptSig,'hex')), - new Buffer('1a','hex') - ); - ret.length.should.equal(0); + var ret = txp._verifySignatures(pubkeys, + new bitcore.Script(new Buffer(validScriptSig, 'hex')), + new Buffer('31103626e162f1cbfab6b95b08c9f6e78aae128523261cb37f8dfd4783cb09a7', 'hex') + ); + ret.should.deep.equal([0, 3]); }); }); diff --git a/test/test.TxProposalsSet.js b/test/test.TxProposalsSet.js index 4872bd569..2c6dfcd86 100644 --- a/test/test.TxProposalsSet.js +++ b/test/test.TxProposalsSet.js @@ -19,7 +19,7 @@ try { } var fakeStorage = copay.FakeStorage; var PrivateKey = copay.PrivateKey || require('../js/models/PrivateKey'); -var TxProposals = copay.TxProposals || require('../js/models/TxProposal'); +var TxProposalsSet = copay.TxProposalsSet || require('../js/models/TxProposalsSet'); var is_browser = (typeof process == 'undefined' || typeof process.versions === 'undefined') var PublicKeyRing = is_browser ? copay.PublicKeyRing : require('soop').load('../js/models/core/PublicKeyRing', { @@ -117,7 +117,7 @@ var createTx = function(toAddress, amountSatStr, utxos, opts, priv, pkr) { inputChainPaths: inputChainPaths, creator: priv.getId(), createdTs: new Date(), - signedBy: priv && tx.countInputSignatures(0) ? {priv.getId(): true} : {}, + signedBy: priv && tx.countInputSignatures(0) ? me : {}, seenBy: priv ? me : {}, builder: b, };