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

View file

@ -36,6 +36,7 @@ function PublicKeyRing(opts) {
this.publicKeysCache = opts.publicKeysCache || {}; this.publicKeysCache = opts.publicKeysCache || {};
this.nicknameFor = opts.nicknameFor || {}; this.nicknameFor = opts.nicknameFor || {};
this.copayerIds = []; this.copayerIds = [];
this.addressToPath = {};
} }
PublicKeyRing.fromObj = function (data) { PublicKeyRing.fromObj = function (data) {
@ -181,7 +182,15 @@ PublicKeyRing.prototype.getRedeemScript = function (index, isChange) {
// TODO this could be cached // TODO this could be cached
PublicKeyRing.prototype.getAddress = function (index, isChange) { PublicKeyRing.prototype.getAddress = function (index, isChange) {
var script = this.getRedeemScript(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 // TODO this could be cached

View file

@ -1,10 +1,8 @@
'use strict'; 'use strict';
var imports = require('soop').imports();
var imports = require('soop').imports(); function Structure() {}
function Structure() {
}
/* /*
@ -17,13 +15,13 @@ var MAX_NON_HARDENED = 0x80000000 - 1;
var SHARED_INDEX = MAX_NON_HARDENED - 0; var SHARED_INDEX = MAX_NON_HARDENED - 0;
var ID_INDEX = MAX_NON_HARDENED - 1; 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.BIP45_PUBLIC_PREFIX = BIP45_PUBLIC_PREFIX;
Structure.Branch = function(address_index, isChange, cosigner_index) { Structure.Branch = function(address_index, isChange, cosigner_index) {
var ret = 'm/'+ var ret = 'm/' +
(typeof cosigner_index !== 'undefined'? cosigner_index: SHARED_INDEX)+'/'+ (typeof cosigner_index !== 'undefined' ? cosigner_index : SHARED_INDEX) + '/' +
(isChange?1:0)+'/'+ (isChange ? 1 : 0) + '/' +
address_index; address_index;
return ret; return ret;
}; };

View file

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

View file

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