refactor _checkSignatures
This commit is contained in:
parent
0af48ff27b
commit
a04cded8b9
|
@ -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() {
|
TxProposal.prototype._getBitcoreTx = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -81,6 +90,13 @@ TxProposal.prototype._getBitcoreTx = function() {
|
||||||
.change(this.changeAddress);
|
.change(this.changeAddress);
|
||||||
|
|
||||||
t._updateChangeOutput();
|
t._updateChangeOutput();
|
||||||
|
|
||||||
|
|
||||||
|
var sigs = this._getCurrentSignatures();
|
||||||
|
_.each(sigs, function(x) {
|
||||||
|
this._addSignaturesToBitcoreTx(t, x.signatures, x.xpub);
|
||||||
|
});
|
||||||
|
|
||||||
return t;
|
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({
|
var action = new TxProposalAction({
|
||||||
copayerId: copayerId,
|
copayerId: copayerId,
|
||||||
type: type,
|
type: type,
|
||||||
signatures: signatures,
|
signatures: signatures,
|
||||||
|
xpub: xpub,
|
||||||
});
|
});
|
||||||
this.actions[copayerId] = action;
|
this.actions[copayerId] = action;
|
||||||
this._updateStatus();
|
this._updateStatus();
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: no sure we should receive xpub or a list of pubkeys (pre derived)
|
TxProposal.prototype._addSignaturesToBitcoreTx = function(t, signatures, xpub) {
|
||||||
TxProposal.prototype.checkSignatures = function(signatures, xpub) {
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var t = this._getBitcoreTx();
|
|
||||||
|
|
||||||
if (signatures.length != this.inputs.length)
|
if (signatures.length != this.inputs.length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -159,17 +173,25 @@ TxProposal.prototype.checkSignatures = function(signatures, xpub) {
|
||||||
|
|
||||||
t.applySignature(s);
|
t.applySignature(s);
|
||||||
oks++;
|
oks++;
|
||||||
} catch (e) {
|
} catch (e) {};
|
||||||
// TODO only for debug now
|
|
||||||
console.log('DEBUG ONLY:', e.message); //TODO
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
return oks === t.inputs.length;
|
|
||||||
|
if (oks != t.inputs.length)
|
||||||
|
throw new Error('wrong signatures');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TxProposal.prototype.sign = function(copayerId, signatures) {
|
TxProposal.prototype.sign = function(copayerId, signatures, xpub) {
|
||||||
this.addAction(copayerId, 'accept', signatures);
|
|
||||||
|
// 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) {
|
TxProposal.prototype.reject = function(copayerId) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ function TxProposalAction(opts) {
|
||||||
this.copayerId = opts.copayerId;
|
this.copayerId = opts.copayerId;
|
||||||
this.type = opts.type || (opts.signatures ? 'accept' : 'reject');
|
this.type = opts.type || (opts.signatures ? 'accept' : 'reject');
|
||||||
this.signatures = opts.signatures;
|
this.signatures = opts.signatures;
|
||||||
|
this.xpub = opts.xpub;
|
||||||
};
|
};
|
||||||
|
|
||||||
TxProposalAction.fromObj = function (obj) {
|
TxProposalAction.fromObj = function (obj) {
|
||||||
|
@ -16,6 +17,7 @@ TxProposalAction.fromObj = function (obj) {
|
||||||
x.copayerId = obj.copayerId;
|
x.copayerId = obj.copayerId;
|
||||||
x.type = obj.type;
|
x.type = obj.type;
|
||||||
x.signatures = obj.signatures;
|
x.signatures = obj.signatures;
|
||||||
|
x.xpub = obj.xpub;
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
|
|
|
@ -585,9 +585,7 @@ CopayServer.prototype.removePendingTx = function(opts, cb) {
|
||||||
CopayServer.prototype._broadcastTx = function(txp, cb) {
|
CopayServer.prototype._broadcastTx = function(txp, cb) {
|
||||||
var raw = txp.getRawTx();
|
var raw = txp.getRawTx();
|
||||||
var bc = this._getBlockExplorer('insight', txp.getNetworkName());
|
var bc = this._getBlockExplorer('insight', txp.getNetworkName());
|
||||||
console.log('[server.js.588:raw:]',raw); //TODO
|
|
||||||
bc.broadcast(raw, function(err, txid) {
|
bc.broadcast(raw, function(err, txid) {
|
||||||
console.log('[server.js.589:err:]',err, txid); //TODO
|
|
||||||
return cb(err, txid);
|
return cb(err, txid);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -622,11 +620,9 @@ CopayServer.prototype.signTx = function(opts, cb) {
|
||||||
|
|
||||||
var copayer = wallet.getCopayer(self.copayerId);
|
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'));
|
return cb(new ClientError('BADSIGNATURES', 'Bad signatures'));
|
||||||
|
|
||||||
txp.sign(self.copayerId, opts.signatures);
|
|
||||||
|
|
||||||
self.storage.storeTx(self.walletId, txp, function(err) {
|
self.storage.storeTx(self.walletId, txp, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
var bc = sinon.stub();
|
||||||
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, utxos);
|
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, utxos);
|
||||||
|
|
|
@ -28,10 +28,10 @@ describe('TXProposal', function() {
|
||||||
describe('#sign', function() {
|
describe('#sign', function() {
|
||||||
it('should sign 2-2', function() {
|
it('should sign 2-2', function() {
|
||||||
var txp = TXP.fromObj(aTXP());
|
var txp = TXP.fromObj(aTXP());
|
||||||
txp.sign('1', theSignatures);
|
txp.sign('1', theSignatures, theXPub);
|
||||||
txp.isAccepted().should.equal(false);
|
txp.isAccepted().should.equal(false);
|
||||||
txp.isRejected().should.equal(false);
|
txp.isRejected().should.equal(false);
|
||||||
txp.sign('2', theSignatures);
|
txp.sign('2', theSignatures, theXPub);
|
||||||
txp.isAccepted().should.equal(true);
|
txp.isAccepted().should.equal(true);
|
||||||
txp.isRejected().should.equal(false);
|
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 theXPriv = 'xprv9s21ZrQH143K2rMHbXTJmWTuFx6ssqn1vyRoZqPkCXYchBSkp5ey8kMJe84sxfXq5uChWH4gk94rWbXZt2opN9kg4ufKGvUM7HQSLjnoh7e';
|
||||||
|
var theXPub = 'xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9';
|
||||||
var theSignatures = ['3045022100896aeb8db75fec22fddb5facf791927a996eb3aee23ee6deaa15471ea46047de02204c0c33f42a9d3ff93d62738712a8c8a5ecd21b45393fdd144e7b01b5a186f1f9'];
|
var theSignatures = ['3045022100896aeb8db75fec22fddb5facf791927a996eb3aee23ee6deaa15471ea46047de02204c0c33f42a9d3ff93d62738712a8c8a5ecd21b45393fdd144e7b01b5a186f1f9'];
|
||||||
|
|
||||||
var aTXP = function() {
|
var aTXP = function() {
|
||||||
|
|
Loading…
Reference in New Issue