refactor txProposal input signature handling

This commit is contained in:
Matias Alejo Garcia 2014-08-21 19:30:31 -04:00
parent e0ccb24b93
commit 18ffaa172a
4 changed files with 49 additions and 39 deletions

View File

@ -25,7 +25,7 @@ function TxProposal(opts) {
this.builder = opts.builder; this.builder = opts.builder;
this.createdTs = opts.createdTs; this.createdTs = opts.createdTs;
this.createdTs = opts.createdTs; this.createdTs = opts.createdTs;
this._inputSignatures = []; this._inputSigners = [];
// CopayerIds // CopayerIds
this.creator = opts.creator; this.creator = opts.creator;
@ -80,21 +80,22 @@ TxProposal.prototype.isPending = function(maxRejectCount) {
TxProposal.prototype._updateSignedBy = function() { TxProposal.prototype._updateSignedBy = function() {
this._inputSignatures = []; this._inputSigners = [];
var tx = this.builder.build(); var tx = this.builder.build();
for (var i in tx.ins) { for (var i in tx.ins) {
var scriptSig = new Script(tx.ins[i].s); var scriptSig = new Script(tx.ins[i].s);
var signatureCount = scriptSig.countSignatures(); var signatureCount = scriptSig.countSignatures();
console.log('[TxProposal.js.88:signatureCount:]', i, '#sig:', signatureCount); //TODO
var info = TxProposal._infoFromRedeemScript(scriptSig); var info = TxProposal._infoFromRedeemScript(scriptSig);
var txSigHash = tx.hashForSignature(info.script, parseInt(i), Transaction.SIGHASH_ALL); var txSigHash = tx.hashForSignature(info.script, parseInt(i), Transaction.SIGHASH_ALL);
var signatureIndexes = TxProposal._verifySignatures(info.keys, scriptSig, txSigHash); var signersPubKey = TxProposal._verifySignatures(info.keys, scriptSig, txSigHash);
if (signatureIndexes.length !== signatureCount) console.log('[TxProposal.js.94:signersPubKey:]', signersPubKey, signatureCount); //TODO
if (signersPubKey.length !== signatureCount)
throw new Error('Invalid signature'); throw new Error('Invalid signature');
this._inputSignatures[i] = signatureIndexes.map(function(i) {
var r = info.keys[i].toString('hex'); this._inputSigners[i] = signersPubKey;
return r;
});
}; };
}; };
@ -163,8 +164,11 @@ TxProposal._formatKeys = function(keys) {
var k = new Key(); var k = new Key();
k.public = keys[i]; k.public = keys[i];
ret.push(k); ret.push({
}; keyObj: k,
keyHex: keys[i].toString('hex'),
});
}
return ret; return ret;
}; };
@ -183,8 +187,8 @@ TxProposal._verifySignatures = function(inKeys, scriptSig, txSigHash) {
var sigRaw = new Buffer(chunk.slice(0, chunk.length - 1)); var sigRaw = new Buffer(chunk.slice(0, chunk.length - 1));
for (var j in keys) { for (var j in keys) {
var k = keys[j]; var k = keys[j];
if (k.verifySignatureSync(txSigHash, sigRaw)) { if (k.keyObj.verifySignatureSync(txSigHash, sigRaw)) {
ret.push(parseInt(j)); ret.push(k.keyHex);
break; break;
} }
} }
@ -241,9 +245,9 @@ TxProposal.prototype.setSent = function(sentTxid) {
TxProposal.prototype._allSignatures = function() { TxProposal.prototype._allSignatures = function() {
var ret = {}; var ret = {};
for (var i in this._inputSignatures) for (var i in this._inputSigners)
for (var j in this._inputSignatures[i]) for (var j in this._inputSigners[i])
ret[this._inputSignatures[i][j]] = true; ret[this._inputSigners[i][j]] = true;
return ret; return ret;
}; };
@ -251,10 +255,10 @@ TxProposal.prototype._allSignatures = function() {
TxProposal.prototype.setCopayers = function(senderId, keyMap, readOnlyPeers) { TxProposal.prototype.setCopayers = function(senderId, keyMap, readOnlyPeers) {
var newCopayer = {}, var newCopayer = {},
oldCopayers = {}, oldCopayers = {},
newSignedBy = {}, newSignedBy = {},
readOnlyPeers = {}, readOnlyPeers = {},
isNew = 1; isNew = 1;
for (var k in this.signedBy) { for (var k in this.signedBy) {
oldCopayers[k] = 1; oldCopayers[k] = 1;
@ -274,7 +278,7 @@ TxProposal.prototype.setCopayers = function(senderId, keyMap, readOnlyPeers) {
} }
var iSig = this._inputSignatures[0]; var iSig = this._inputSigners[0];
for (var i in iSig) { for (var i in iSig) {
var copayerId = keyMap[iSig[i]]; var copayerId = keyMap[iSig[i]];
if (!copayerId) if (!copayerId)

View File

@ -173,20 +173,26 @@ txId: ntxid
*/ */
Wallet.prototype._getKeyMap = function(txp) { Wallet.prototype._getKeyMap = function(txp) {
preconditions.checkArgument(txp); preconditions.checkArgument(txp);
console.log('[Wallet.js.175:txp:]',txp); //TODO
var keyMap = this.publicKeyRing.copayersForPubkeys(txp._inputSignatures[0], txp.inputChainPaths); var keyMap = this.publicKeyRing.copayersForPubkeys(txp._inputSigners[0], txp.inputChainPaths);
var inSig = JSON.stringify(txp._inputSignatures[0].sort()); var inSig = JSON.stringify(txp._inputSigners[0].sort());
console.log('[Wallet.js.179:inSig:]',inSig); //TODO
if (JSON.stringify(Object.keys(keyMap).sort()) !== inSig) { if (JSON.stringify(Object.keys(keyMap).sort()) !== inSig) {
throw new Error('inputSignatures dont match know copayers pubkeys'); throw new Error('inputSignatures dont match know copayers pubkeys');
} }
var keyMapStr = JSON.stringify(keyMap); var keyMapStr = JSON.stringify(keyMap);
console.log('[Wallet.js.187:keyMapStr:]',keyMapStr); //TODO
// All inputs must be signed with the same copayers // All inputs must be signed with the same copayers
for (var i in txp._inputSignatures) { for (var i in txp._inputSigners) {
console.log('[Wallet.js.190]',i); //TODO
if (!i) continue; if (!i) continue;
var inSigX = JSON.stringify(txp._inputSignatures[i].sort()); var inSigX = JSON.stringify(txp._inputSigners[i].sort());
if (inSigX !== inSig) if (inSigX !== inSig)
throw new Error('found inputs with different signatures:'); throw new Error('found inputs with different signatures:');
} }

View File

@ -189,7 +189,7 @@ describe('TxProposal', function() {
var txp = dummyProposal; var txp = dummyProposal;
var tx = dummyProposal.builder.build(); var tx = dummyProposal.builder.build();
var ret = TxProposal._verifySignatures(pubkeys, validScriptSig, tx.hashForSignature()); var ret = TxProposal._verifySignatures(pubkeys, validScriptSig, tx.hashForSignature());
ret.should.deep.equal([0, 3]); ret.should.deep.equal(['03197599f6e209cefef07da2fddc6fe47715a70162c531ffff8e611cef23dfb70d', '03a94351fecc4328bb683bf93a1aa67378374904eac5980c7966723a51897c56e3']);
}); });
it('#_infoFromRedeemScript', function() { it('#_infoFromRedeemScript', function() {
var info = TxProposal._infoFromRedeemScript(validScriptSig); var info = TxProposal._infoFromRedeemScript(validScriptSig);
@ -202,7 +202,7 @@ describe('TxProposal', function() {
}); });
it('#_updateSignedBy', function() { it('#_updateSignedBy', function() {
var txp = dummyProposal; var txp = dummyProposal;
txp._inputSignatures.should.deep.equal([ txp._inputSigners.should.deep.equal([
['03197599f6e209cefef07da2fddc6fe47715a70162c531ffff8e611cef23dfb70d', '03a94351fecc4328bb683bf93a1aa67378374904eac5980c7966723a51897c56e3'] ['03197599f6e209cefef07da2fddc6fe47715a70162c531ffff8e611cef23dfb70d', '03a94351fecc4328bb683bf93a1aa67378374904eac5980c7966723a51897c56e3']
]); ]);
}); });
@ -302,7 +302,7 @@ describe('TxProposal', function() {
txp.signedBy = { txp.signedBy = {
'hugo': 1 'hugo': 1
}; };
txp._inputSignatures = [ txp._inputSigners = [
['pkX'] ['pkX']
]; ];
(function() { (function() {
@ -319,7 +319,7 @@ describe('TxProposal', function() {
txp.signedBy = { txp.signedBy = {
creator: 1 creator: 1
}; };
txp._inputSignatures = [ txp._inputSigners = [
['pk0', 'pkX'] ['pk0', 'pkX']
]; ];
(function() { (function() {
@ -333,7 +333,7 @@ describe('TxProposal', function() {
it.skip("should be signed by sender", function() { it.skip("should be signed by sender", function() {
var txp = dummyProposal; var txp = dummyProposal;
var ts = Date.now(); var ts = Date.now();
txp._inputSignatures = [ txp._inputSigners = [
['pk1', 'pk0'] ['pk1', 'pk0']
]; ];
txp.signedBy = { txp.signedBy = {
@ -352,7 +352,7 @@ describe('TxProposal', function() {
it("should set signedBy (trivial case)", function() { it("should set signedBy (trivial case)", function() {
var txp = dummyProposal; var txp = dummyProposal;
var ts = Date.now(); var ts = Date.now();
txp._inputSignatures = [ txp._inputSigners = [
['pk1', 'pk0'] ['pk1', 'pk0']
]; ];
txp.signedBy = { txp.signedBy = {
@ -370,7 +370,7 @@ describe('TxProposal', function() {
it("should assign creator", function() { it("should assign creator", function() {
var txp = dummyProposal; var txp = dummyProposal;
var ts = Date.now(); var ts = Date.now();
txp._inputSignatures = [ txp._inputSigners = [
['pk0'] ['pk0']
]; ];
txp.signedBy = {}; txp.signedBy = {};
@ -392,7 +392,7 @@ describe('TxProposal', function() {
txp.signedBy = {}; txp.signedBy = {};
delete txp['creator']; delete txp['creator'];
delete txp['creatorTs']; delete txp['creatorTs'];
txp._inputSignatures = [ txp._inputSigners = [
['pk0', 'pk1'] ['pk0', 'pk1']
]; ];
(function() { (function() {
@ -411,7 +411,7 @@ describe('TxProposal', function() {
it("if signed, should not change ts", function() { it("if signed, should not change ts", function() {
var txp = dummyProposal; var txp = dummyProposal;
var ts = Date.now(); var ts = Date.now();
txp._inputSignatures = [ txp._inputSigners = [
['pk0', 'pk1'] ['pk0', 'pk1']
]; ];
txp.creator = 'creator'; txp.creator = 'creator';

View File

@ -219,7 +219,7 @@ describe('Wallet model', function() {
var t = w.txProposals; var t = w.txProposals;
var txp = t.txps[ntxid]; var txp = t.txps[ntxid];
Object.keys(txp._inputSignatures).length.should.equal(1); Object.keys(txp._inputSigners).length.should.equal(1);
var tx = txp.builder.build(); var tx = txp.builder.build();
should.exist(tx); should.exist(tx);
chai.expect(txp.comment).to.be.null; chai.expect(txp.comment).to.be.null;
@ -1108,7 +1108,7 @@ describe('Wallet model', function() {
}; };
}); });
var txp = { var txp = {
_inputSignatures: [ _inputSigners: [
['123'] ['123']
], ],
inputChainPaths: ['/m/1'], inputChainPaths: ['/m/1'],
@ -1126,7 +1126,7 @@ describe('Wallet model', function() {
}; };
}); });
var txp = { var txp = {
_inputSignatures: [ _inputSigners: [
['234'] ['234']
], ],
inputChainPaths: ['/m/1'], inputChainPaths: ['/m/1'],
@ -1145,7 +1145,7 @@ describe('Wallet model', function() {
}; };
}); });
var txp = { var txp = {
_inputSignatures: [ _inputSigners: [
['234', '123'] ['234', '123']
], ],
inputChainPaths: ['/m/1'], inputChainPaths: ['/m/1'],
@ -1165,7 +1165,7 @@ describe('Wallet model', function() {
}; };
}); });
var txp = { var txp = {
_inputSignatures: [ _inputSigners: [
['234', '123'], ['234', '123'],
['234'] ['234']
], ],