diff --git a/packages/bitcore-node/src/models/transaction.ts b/packages/bitcore-node/src/models/transaction.ts index a5175ecb79f..529e45331fd 100644 --- a/packages/bitcore-node/src/models/transaction.ts +++ b/packages/bitcore-node/src/models/transaction.ts @@ -14,6 +14,30 @@ import * as lodash from 'lodash'; const Chain = require('../chain'); +const addressCacheStore = { + list: [] as Array, + map: new Map() as Map +}; + +function getCachedAddress(chain: string, network: string, script: string){ + const result = addressCacheStore.map.get(`${chain}:${network}:${script}`); + if (result) { + addressCacheStore.list.push(`${chain}:${network}:${script}`); + if (addressCacheStore.list.length > 10000) { + addressCacheStore.map.delete(addressCacheStore.list.shift()); + } + } + return result; +} + +function setCachedAddress(chain: string, network: string, script: any, address: any) { + addressCacheStore.map.set(`${chain}:${network}:${script}`, address); + addressCacheStore.list.push(`${chain}:${network}:${script}`); + if (addressCacheStore.list.length > 10000) { + addressCacheStore.map.delete(addressCacheStore.list.shift()); + } +} + export type ITransaction = { txid: string; chain: string; @@ -216,12 +240,18 @@ export class Transaction extends BaseModel { continue; } let address = ''; - let scriptBuffer = output.script && output.script.toBuffer(); - if (scriptBuffer) { - address = output.script.toAddress(network).toString(true); - if (address === 'false' && output.script.classify() === 'Pay to public key') { - let hash = Chain[chain].lib.crypto.Hash.sha256ripemd160(output.script.chunks[0].buf); - address = Chain[chain].lib.Address(hash, network).toString(true); + if (output.script) { + const hexScript = output.script.toHex(); + const cachedAddress = getCachedAddress(chain, network, hexScript); + if (cachedAddress) { + address = cachedAddress; + } else { + address = output.script.toAddress(network).toString(true); + if (address === 'false' && output.script.classify() === 'Pay to public key') { + let hash = Chain[chain].lib.crypto.Hash.sha256ripemd160(output.script.chunks[0].buf); + address = Chain[chain].lib.Address(hash, network).toString(true); + } + setCachedAddress(chain, network, output.script.toHex(), address); } } @@ -242,7 +272,7 @@ export class Transaction extends BaseModel { mintHeight: height, coinbase: isCoinbase, value: output.satoshis, - script: scriptBuffer, + script: output.script.toBuffer(), spentHeight: SpentHeightIndicators.unspent, wallets: [] } diff --git a/packages/bitcore-node/src/types/namespaces/Bitcoin/Transaction.ts b/packages/bitcore-node/src/types/namespaces/Bitcoin/Transaction.ts index eac4e493c70..cfe5aad00f0 100644 --- a/packages/bitcore-node/src/types/namespaces/Bitcoin/Transaction.ts +++ b/packages/bitcore-node/src/types/namespaces/Bitcoin/Transaction.ts @@ -3,6 +3,7 @@ export type BitcoinAddress = { }; export type BitcoinScript = { toBuffer: () => Buffer; + toHex: () => string; classify: () => string; chunks: Array<{ buf: Buffer }>; toAddress: (network: string) => BitcoinAddress;