mirror of https://github.com/BTCPrivate/copay.git
refactor txProposal input signature handling
This commit is contained in:
parent
e0ccb24b93
commit
18ffaa172a
|
@ -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)
|
||||||
|
|
|
@ -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:');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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']
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue