parent
cba9d3e439
commit
8144743eda
@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2014-2018, MyMonero.com
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
const monero_utils = require("./monero_cryptonote_utils_instance");
|
||||
|
||||
// Managed caches - Can be used by apps which can't send a mutable_keyImagesByCacheKey
|
||||
|
||||
type KeyImageCache = { [cacheIndex: string]: string };
|
||||
type KeyImageCacheMap = { [address: string]: KeyImageCache };
|
||||
|
||||
const keyImagesByWalletId: KeyImageCacheMap = {};
|
||||
|
||||
/**
|
||||
* @description Performs a memoized computation of a key image
|
||||
* @param {KeyImageCache} keyImageCache
|
||||
* @param {string} txPubKey
|
||||
* @param {number} outIndex
|
||||
* @param {string} address
|
||||
* @param {string} privViewKey
|
||||
* @param {string} pubSpendKey
|
||||
* @param {string} privSpendKey
|
||||
* @returns
|
||||
*/
|
||||
export function keyImage(
|
||||
keyImageCache: KeyImageCache,
|
||||
txPubKey: string,
|
||||
outIndex: number,
|
||||
address: string,
|
||||
privViewKey: string,
|
||||
pubSpendKey: string,
|
||||
privSpendKey: string,
|
||||
) {
|
||||
const cacheIndex = `${txPubKey}:${address}:${outIndex}`;
|
||||
const cachedKeyImage = keyImageCache[cacheIndex];
|
||||
|
||||
if (cachedKeyImage) {
|
||||
return cachedKeyImage;
|
||||
}
|
||||
|
||||
const { key_image } = monero_utils.generate_key_image(
|
||||
txPubKey,
|
||||
privViewKey,
|
||||
pubSpendKey,
|
||||
privSpendKey,
|
||||
outIndex,
|
||||
);
|
||||
|
||||
// cache the computed key image
|
||||
keyImageCache[cacheIndex] = key_image;
|
||||
|
||||
return key_image;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description Get a key image cache, that's mapped by address
|
||||
* @export
|
||||
* @param {string} address
|
||||
*/
|
||||
export function getKeyImageCache(address: string) {
|
||||
const cacheId = parseAddress(address);
|
||||
|
||||
let cache = keyImagesByWalletId[cacheId];
|
||||
if (!cache) {
|
||||
cache = {};
|
||||
keyImagesByWalletId[cacheId] = cache;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Clears a key image cache that's mapped by the users address
|
||||
*
|
||||
*
|
||||
* IMPORTANT: Ensure you call this method when you want to clear your wallet from
|
||||
* memory or delete it, or else you could leak key images and public addresses.
|
||||
* @export
|
||||
* @param {string} address
|
||||
*/
|
||||
export function clearKeyImageCache(address: string) {
|
||||
const cacheId = parseAddress(address);
|
||||
|
||||
delete keyImagesByWalletId[cacheId];
|
||||
|
||||
const cache = keyImagesByWalletId[cacheId];
|
||||
|
||||
if (cache) {
|
||||
throw "Key image cache still exists after deletion";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Normalize an address before using it to access the key image cache map as a key
|
||||
* @param {string} address
|
||||
*/
|
||||
function parseAddress(address: string) {
|
||||
// NOTE: making the assumption that public_address is unique enough to identify a wallet for caching....
|
||||
// FIXME: with subaddresses, is that still the case? would we need to split them up by subaddr anyway?
|
||||
if (!address) {
|
||||
throw "Address does not exist";
|
||||
}
|
||||
|
||||
return address.toString();
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
// Copyright (c) 2014-2018, MyMonero.com
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
"use strict";
|
||||
//
|
||||
const monero_utils = require("./monero_cryptonote_utils_instance");
|
||||
//
|
||||
const Lazy_KeyImage = function(
|
||||
mutable_keyImagesByCacheKey, // pass a mutable JS dictionary
|
||||
tx_pub_key,
|
||||
out_index,
|
||||
public_address,
|
||||
view_key__private,
|
||||
spend_key__public,
|
||||
spend_key__private,
|
||||
) {
|
||||
var cache_index = tx_pub_key + ":" + public_address + ":" + out_index;
|
||||
const cached__key_image = mutable_keyImagesByCacheKey[cache_index];
|
||||
if (
|
||||
typeof cached__key_image !== "undefined" &&
|
||||
cached__key_image !== null
|
||||
) {
|
||||
return cached__key_image;
|
||||
}
|
||||
var key_image = monero_utils.generate_key_image(
|
||||
tx_pub_key,
|
||||
view_key__private,
|
||||
spend_key__public,
|
||||
spend_key__private,
|
||||
out_index,
|
||||
).key_image;
|
||||
// cache:
|
||||
mutable_keyImagesByCacheKey[cache_index] = key_image;
|
||||
//
|
||||
return key_image;
|
||||
};
|
||||
exports.Lazy_KeyImage = Lazy_KeyImage;
|
||||
//
|
||||
//
|
||||
// Managed caches - Can be used by apps which can't send a mutable_keyImagesByCacheKey
|
||||
const __global_managed_keyImageCaches_by_walletId = {};
|
||||
function _managedKeyImageCacheWalletIdForWalletWith(public_address) {
|
||||
// NOTE: making the assumption that public_address is unique enough to identify a wallet for caching....
|
||||
// FIXME: with subaddresses, is that still the case? would we need to split them up by subaddr anyway?
|
||||
if (
|
||||
public_address == "" ||
|
||||
!public_address ||
|
||||
typeof public_address == "undefined"
|
||||
) {
|
||||
throw "managedKeyImageCacheIdentifierForWalletWith: Illegal public_address";
|
||||
}
|
||||
return "" + public_address;
|
||||
}
|
||||
const Lazy_KeyImageCacheForWalletWith = function(public_address) {
|
||||
var cacheId = _managedKeyImageCacheWalletIdForWalletWith(public_address);
|
||||
var cache = __global_managed_keyImageCaches_by_walletId[cacheId];
|
||||
if (typeof cache === "undefined" || !cache) {
|
||||
cache = {};
|
||||
__global_managed_keyImageCaches_by_walletId[cacheId] = cache;
|
||||
}
|
||||
return cache;
|
||||
};
|
||||
exports.Lazy_KeyImageCacheForWalletWith = Lazy_KeyImageCacheForWalletWith;
|
||||
//
|
||||
const DeleteManagedKeyImagesForWalletWith = function(public_address) {
|
||||
// IMPORTANT: Ensure you call this method when you want to clear your wallet from
|
||||
// memory or delete it, or else you could leak key images and public addresses.
|
||||
const cacheId = _managedKeyImageCacheWalletIdForWalletWith(public_address);
|
||||
delete __global_managed_keyImageCaches_by_walletId[cacheId];
|
||||
//
|
||||
const cache = __global_managed_keyImageCaches_by_walletId[cacheId];
|
||||
if (typeof cache !== "undefined") {
|
||||
throw "Key image cache still exists after deletion";
|
||||
}
|
||||
};
|
||||
exports.DeleteManagedKeyImagesForWalletWith = DeleteManagedKeyImagesForWalletWith;
|
Loading…
Reference in new issue