Merge pull request #496 from maraoz/optimize/tx-signing
Optimize tx signing by sending derivation path
This commit is contained in:
commit
bfab32df48
5 changed files with 40 additions and 16 deletions
|
|
@ -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++) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
'use strict';
|
'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
|
* 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 PURPOSE = 45;
|
||||||
var MAX_NON_HARDENED = 0x80000000 - 1;
|
var MAX_NON_HARDENED = 0x80000000 - 1;
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue