Merge pull request #1772 from eordano/performance/cacheAddressesInfo

Cache addressesInfo
This commit is contained in:
Matias Alejo Garcia 2014-11-12 16:53:51 -03:00
commit 546d0c181e
2 changed files with 46 additions and 10 deletions

View file

@ -327,8 +327,6 @@ PublicKeyRing.prototype.getRedeemScript = function(index, isChange, copayerIndex
* *
* Caches the address to the branch in the member addressToPath * Caches the address to the branch in the member addressToPath
* *
* @TODO this could be cached
*
* @param {number} index - the index for the shared address * @param {number} index - the index for the shared address
* @param {boolean} isChange - whether to derive a change address o receive address * @param {boolean} isChange - whether to derive a change address o receive address
* @param {number} copayerIndex - the index of the copayer that requested the derivation * @param {number} copayerIndex - the index of the copayer that requested the derivation
@ -336,10 +334,27 @@ PublicKeyRing.prototype.getRedeemScript = function(index, isChange, copayerIndex
*/ */
PublicKeyRing.prototype.getAddress = function(index, isChange, id) { PublicKeyRing.prototype.getAddress = function(index, isChange, id) {
var copayerIndex = this.getCosigner(id); var copayerIndex = this.getCosigner(id);
var script = this.getRedeemScript(index, isChange, copayerIndex); if (!this._cachedAddress(index, isChange, id)) {
var address = Address.fromScript(script, this.network.name); var script = this.getRedeemScript(index, isChange, copayerIndex);
this.addressToPath[address.toString()] = HDPath.FullBranch(index, isChange, copayerIndex); var address = Address.fromScript(script, this.network.name);
return address; this.addressToPath[address.toString()] = HDPath.FullBranch(index, isChange, copayerIndex);
this._cacheAddress(index, isChange, copayerIndex, address);
}
return this._cachedAddress(index, isChange, copayerIndex);
};
PublicKeyRing.prototype._cacheAddress = function(index, isChange, copayerIndex, address) {
var changeIndex = isChange ? 1 : 0;
if (!this._cacheAddressMap) this._cacheAddressMap = {};
if (!this._cacheAddressMap[index]) this._cacheAddressMap[index] = {};
if (!this._cacheAddressMap[index][changeIndex]) this._cacheAddressMap[index][changeIndex] = {};
this._cacheAddressMap[index][changeIndex][copayerIndex] = address;
};
PublicKeyRing.prototype._cachedAddress = function(index, isChange, copayerIndex) {
var changeIndex = isChange ? 1 : 0;
if (!this._cacheAddressMap) return undefined;
if (!this._cacheAddressMap[index]) return undefined;
if (!this._cacheAddressMap[index][changeIndex]) return undefined;
return this._cacheAddressMap[index][changeIndex][copayerIndex];
}; };
/** /**
@ -348,8 +363,6 @@ PublicKeyRing.prototype.getAddress = function(index, isChange, id) {
* *
* Overloaded to receive a PubkeyString or a consigner index * Overloaded to receive a PubkeyString or a consigner index
* *
* @TODO: Couldn't really figure out what does this do
*
* @param {number|string} id public key in hex format, or the copayer's index * @param {number|string} id public key in hex format, or the copayer's index
* @return ???? * @return ????
*/ */
@ -458,14 +471,13 @@ PublicKeyRing.prototype.getCosigner = function(pubKey) {
* @returns {AddressInfo[]} * @returns {AddressInfo[]}
*/ */
PublicKeyRing.prototype.getAddressesInfo = function(opts, pubkey) { PublicKeyRing.prototype.getAddressesInfo = function(opts, pubkey) {
var ret = []; var ret = [];
var self = this; var self = this;
var copayerIndex = pubkey && this.getCosigner(pubkey); var copayerIndex = pubkey && this.getCosigner(pubkey);
this.indexes.forEach(function(index) { this.indexes.forEach(function(index) {
ret = ret.concat(self.getAddressesInfoForIndex(index, opts, copayerIndex)); ret = ret.concat(self.getAddressesInfoForIndex(index, opts, copayerIndex));
}); });
return ret; return ret;
}; };

View file

@ -148,6 +148,30 @@ describe('PublicKeyRing model', function() {
}); });
}); });
it('caches calls to getAddress', function() {
var setup = getCachedW();
var pubkeyring = setup.w;
var address = pubkeyring.getAddress(3, false, 4);
(pubkeyring._cacheAddressMap[3][0][4]).should.equal(address);
});
it('getAddress cache hit doesn\'t alter state', function() {
var setup = getCachedW();
var pubkeyring = setup.w;
var spySave;
pubkeyring.getAddress(3, false, 4);
spySave = sinon.stub(pubkeyring, '_cacheAddress');
spySave.onFirstCall().throws(new Error());
pubkeyring.getAddress(3, false, 4);
spySave.restore();
});
it('should return PublicKeyRing addresses', function() { it('should return PublicKeyRing addresses', function() {
var k = createW(); var k = createW();
var w = k.w; var w = k.w;