Merge pull request #496 from maraoz/optimize/tx-signing

Optimize tx signing by sending derivation path
This commit is contained in:
Matias Alejo Garcia 2014-05-30 15:41:54 -03:00
commit bfab32df48
5 changed files with 40 additions and 16 deletions

View File

@ -61,8 +61,11 @@ PrivateKey.prototype._getHK = function(path) {
return this.bip.derive(path);
};
PrivateKey.prototype.get = function(index,isChange) {
var path = Structure.FullBranch(index, isChange);
PrivateKey.prototype.getForPaths = function(paths) {
return paths.map(this.getForPath.bind(this));
};
PrivateKey.prototype.getForPath = function(path) {
var pk = this.privateKeyCache[path];
if (!pk) {
var derivedHK = this._getHK(path);
@ -73,6 +76,11 @@ PrivateKey.prototype.get = function(index,isChange) {
return wk;
};
PrivateKey.prototype.get = function(index,isChange) {
var path = Structure.FullBranch(index, isChange);
return this.getForPath(path);
};
PrivateKey.prototype.getAll = function(addressIndex, changeAddressIndex) {
var ret = [];
for(var i=0;i<addressIndex; i++) {

View File

@ -36,6 +36,7 @@ function PublicKeyRing(opts) {
this.publicKeysCache = opts.publicKeysCache || {};
this.nicknameFor = opts.nicknameFor || {};
this.copayerIds = [];
this.addressToPath = {};
}
PublicKeyRing.fromObj = function (data) {
@ -181,7 +182,15 @@ PublicKeyRing.prototype.getRedeemScript = function (index, isChange) {
// TODO this could be cached
PublicKeyRing.prototype.getAddress = function (index, isChange) {
var script = this.getRedeemScript(index,isChange);
return Address.fromScript(script, this.network.name);
var address = Address.fromScript(script, this.network.name);
this.addressToPath[address.toString()] = Structure.FullBranch(index, isChange);
return address;
};
PublicKeyRing.prototype.pathForAddress = function(address) {
var path = this.addressToPath[address];
if (!path) throw new Error('Couldn\'t find path for address '+address);
return path;
};
// TODO this could be cached

View File

@ -1,15 +1,13 @@
'use strict';
var imports = require('soop').imports();
var imports = require('soop').imports();
function Structure() {
}
function Structure() {}
/*
* Based on https://github.com/maraoz/bips/blob/master/bip-NNNN.mediawiki
* m / purpose' / cosigner_index / change / address_index
* m / purpose' / cosigner_index / change / address_index
*/
var PURPOSE = 45;
var MAX_NON_HARDENED = 0x80000000 - 1;
@ -17,13 +15,13 @@ var MAX_NON_HARDENED = 0x80000000 - 1;
var SHARED_INDEX = MAX_NON_HARDENED - 0;
var ID_INDEX = MAX_NON_HARDENED - 1;
var BIP45_PUBLIC_PREFIX = 'm/'+ PURPOSE+'\'';
var BIP45_PUBLIC_PREFIX = 'm/' + PURPOSE + '\'';
Structure.BIP45_PUBLIC_PREFIX = BIP45_PUBLIC_PREFIX;
Structure.Branch = function(address_index, isChange, cosigner_index) {
var ret = 'm/'+
(typeof cosigner_index !== 'undefined'? cosigner_index: SHARED_INDEX)+'/'+
(isChange?1:0)+'/'+
var ret = 'm/' +
(typeof cosigner_index !== 'undefined' ? cosigner_index : SHARED_INDEX) + '/' +
(isChange ? 1 : 0) + '/' +
address_index;
return ret;
};

View File

@ -22,6 +22,7 @@ function TxProposal(opts) {
this.builder = opts.builder;
this.sentTs = opts.sentTs || null;
this.sentTxid = opts.sentTxid || null;
this.inputChainPaths = opts.inputChainPaths || [];
}
TxProposal.prototype.toObj = function() {

View File

@ -432,7 +432,7 @@ Wallet.prototype.sign = function(ntxid, cb) {
}
var pkr = self.publicKeyRing;
var keys = self.privateKey.getAll(pkr.addressIndex, pkr.changeAddressIndex);
var keys = self.privateKey.getForPaths(txp.inputChainPaths);
var b = txp.builder;
var before = b.signaturesAdded;
@ -626,9 +626,15 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, utxos, opts) {
amountSat: amountSat
}]);
var signRet;
var selectedUtxos = b.getSelectedUnspent();
var inputChainPaths = selectedUtxos.map(function(utxo) {
return pkr.pathForAddress(utxo.address);
});
if (priv) {
var signed = b.sign(priv.getAll(pkr.addressIndex, pkr.changeAddressIndex));
var keys = priv.getForPaths(inputChainPaths);
var signed = b.sign(keys);
}
var myId = this.getMyCopayerId();
var now = Date.now();
@ -640,6 +646,7 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, utxos, opts) {
if (priv) meSeen[myId] = now;
var data = {
inputChainPaths: inputChainPaths,
signedBy: me,
seenBy: meSeen,
creator: myId,
@ -647,7 +654,8 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, utxos, opts) {
builder: b,
};
return this.txProposals.add(data);
var ntxid = this.txProposals.add(data);
return ntxid;
};
Wallet.prototype.disconnect = function() {