refactor _checkSignatures

This commit is contained in:
Matias Alejo Garcia 2015-02-13 21:00:12 -03:00
parent 0af48ff27b
commit a04cded8b9
5 changed files with 48 additions and 37 deletions

View File

@ -69,6 +69,15 @@ TxProposal.prototype._updateStatus = function() {
};
TxProposal.prototype._getCurrentSignatures = function() {
return _.map(_.some(this.actions, 'xpub'), function(x) {
return {
signatures: x.signatures,
xpub: xpub,
};
});
};
TxProposal.prototype._getBitcoreTx = function() {
var self = this;
@ -81,6 +90,13 @@ TxProposal.prototype._getBitcoreTx = function() {
.change(this.changeAddress);
t._updateChangeOutput();
var sigs = this._getCurrentSignatures();
_.each(sigs, function(x) {
this._addSignaturesToBitcoreTx(t, x.signatures, x.xpub);
});
return t;
};
@ -121,22 +137,20 @@ TxProposal.prototype.getActionBy = function(copayerId) {
};
};
TxProposal.prototype.addAction = function(copayerId, type, signatures) {
TxProposal.prototype.addAction = function(copayerId, type, signatures, xpub) {
var action = new TxProposalAction({
copayerId: copayerId,
type: type,
signatures: signatures,
xpub: xpub,
});
this.actions[copayerId] = action;
this._updateStatus();
};
// TODO: no sure we should receive xpub or a list of pubkeys (pre derived)
TxProposal.prototype.checkSignatures = function(signatures, xpub) {
TxProposal.prototype._addSignaturesToBitcoreTx = function(t, signatures, xpub) {
var self = this;
var t = this._getBitcoreTx();
if (signatures.length != this.inputs.length)
return false;
@ -159,17 +173,25 @@ TxProposal.prototype.checkSignatures = function(signatures, xpub) {
t.applySignature(s);
oks++;
} catch (e) {
// TODO only for debug now
console.log('DEBUG ONLY:', e.message); //TODO
};
} catch (e) {};
});
return oks === t.inputs.length;
if (oks != t.inputs.length)
throw new Error('wrong signatures');
};
TxProposal.prototype.sign = function(copayerId, signatures) {
this.addAction(copayerId, 'accept', signatures);
TxProposal.prototype.sign = function(copayerId, signatures, xpub) {
// Tests signatures are OK
var t = this._getBitcoreTx();
try {
this._addSignaturesToBitcoreTx(t, signatures, xpub);
this.addAction(copayerId, 'accept', signatures, xpub);
return true;
} catch (e) {
return false;
}
};
TxProposal.prototype.reject = function(copayerId) {

View File

@ -7,6 +7,7 @@ function TxProposalAction(opts) {
this.copayerId = opts.copayerId;
this.type = opts.type || (opts.signatures ? 'accept' : 'reject');
this.signatures = opts.signatures;
this.xpub = opts.xpub;
};
TxProposalAction.fromObj = function (obj) {
@ -16,6 +17,7 @@ TxProposalAction.fromObj = function (obj) {
x.copayerId = obj.copayerId;
x.type = obj.type;
x.signatures = obj.signatures;
x.xpub = obj.xpub;
return x;
};

View File

@ -585,9 +585,7 @@ CopayServer.prototype.removePendingTx = function(opts, cb) {
CopayServer.prototype._broadcastTx = function(txp, cb) {
var raw = txp.getRawTx();
var bc = this._getBlockExplorer('insight', txp.getNetworkName());
console.log('[server.js.588:raw:]',raw); //TODO
bc.broadcast(raw, function(err, txid) {
console.log('[server.js.589:err:]',err, txid); //TODO
return cb(err, txid);
})
};
@ -622,11 +620,9 @@ CopayServer.prototype.signTx = function(opts, cb) {
var copayer = wallet.getCopayer(self.copayerId);
if (!txp.checkSignatures(opts.signatures, copayer.xPubKey))
if (!txp.sign(self.copayerId, opts.signatures, copayer.xPubKey))
return cb(new ClientError('BADSIGNATURES', 'Bad signatures'));
txp.sign(self.copayerId, opts.signatures);
self.storage.storeTx(self.walletId, txp, function(err) {
if (err) return cb(err);

View File

@ -114,7 +114,14 @@ helpers.createUtxos = function(server, wallet, amounts, cb) {
};
helpers.stubBlockExplorer = function(server, utxos, txid) {
helpers.stubBlockExplorer = function(server, inUtxos, txid) {
var utxos = _.map(inUtxos, function(x) {
x.toObject = function() {
return this;
};
return x;
});
var bc = sinon.stub();
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, utxos);

View File

@ -28,10 +28,10 @@ describe('TXProposal', function() {
describe('#sign', function() {
it('should sign 2-2', function() {
var txp = TXP.fromObj(aTXP());
txp.sign('1', theSignatures);
txp.sign('1', theSignatures, theXPub);
txp.isAccepted().should.equal(false);
txp.isRejected().should.equal(false);
txp.sign('2', theSignatures);
txp.sign('2', theSignatures, theXPub);
txp.isAccepted().should.equal(true);
txp.isRejected().should.equal(false);
});
@ -59,26 +59,10 @@ describe('TXProposal', function() {
});
});
describe('#checkSignatures', function() {
it('should check signatures', function() {
var txp = TXP.fromObj(aTXP());
var xpriv = new Bitcore.HDPrivateKey(theXPriv);
var priv = xpriv.derive(txp.inputPaths[0]).privateKey;
var t = txp._getBitcoreTx();
t.sign(priv);
var s = t.getSignatures(priv)[0].signature.toDER().toString('hex');
var xpub = new Bitcore.HDPublicKey(xpriv);
var res = txp.checkSignatures([s], xpub);
res.should.equal(true);
});
});
});
var theXPriv = 'xprv9s21ZrQH143K2rMHbXTJmWTuFx6ssqn1vyRoZqPkCXYchBSkp5ey8kMJe84sxfXq5uChWH4gk94rWbXZt2opN9kg4ufKGvUM7HQSLjnoh7e';
var theXPub = 'xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9';
var theSignatures = ['3045022100896aeb8db75fec22fddb5facf791927a996eb3aee23ee6deaa15471ea46047de02204c0c33f42a9d3ff93d62738712a8c8a5ecd21b45393fdd144e7b01b5a186f1f9'];
var aTXP = function() {