Browse Source

Make getAsyncAddress for limit CPU usage

master
Loëck Vézien 7 years ago
parent
commit
c177f6485d
No known key found for this signature in database GPG Key ID: CBCDCE384E853AC4
  1. 92
      src/helpers/btc.js
  2. 30
      src/internals/accounts/sync.js

92
src/helpers/btc.js

@ -98,6 +98,9 @@ export async function getAccount({
}),
})
const getAsyncAddress = params =>
new Promise(resolve => setTimeout(() => resolve(getAddress(params)), 100))
const getLastAddress = (addresses, txs) => {
const txsAddresses = [...txs.inputs.map(tx => tx.prev_out.addr), ...txs.out.map(tx => tx.addr)]
const lastAddress = addresses.reverse().find(a => txsAddresses.includes(a.address)) || {
@ -110,48 +113,53 @@ export async function getAccount({
}
const nextPath = (index = 0) =>
Promise.all(
Array.from(new Array(gapLimit).keys()).map(v =>
Promise.all([
getAddress({ type: 'external', index: v + index }),
getAddress({ type: 'internal', index: v + index }),
]),
),
).then(async results => {
const addresses = results.reduce((result, v) => [...result, ...v], [])
const listAddresses = addresses.map(a => a.address)
allAddresses = [...new Set([...allAddresses, ...listAddresses])]
const { txs } = await getTransactions(listAddresses)
const hasTransactions = txs.length > 0
transactions = [...transactions, ...txs.map(computeTransaction(allAddresses))]
lastAddress = hasTransactions ? getLastAddress(addresses, txs[0]) : lastAddress
if (hasTransactions) {
return nextPath(index + (gapLimit - 1))
}
return {
balance: transactions.reduce((result, v) => {
result += v.balance
return result
}, 0),
allAddresses,
transactions,
...(lastAddress !== null
? {
currentIndex: lastAddress.index,
address: lastAddress.address,
}
: {
currentIndex: 0,
address: getAddress({ type: 'external', index: 0 }).address,
}),
}
})
Array.from(new Array(gapLimit).keys())
.reduce(
(promise, v) =>
promise.then(async results => {
const result = await Promise.all([
getAsyncAddress({ type: 'external', index: v + index }),
getAsyncAddress({ type: 'internal', index: v + index }),
])
return [...results, result]
}),
Promise.resolve([]),
)
.then(async results => {
const addresses = results.reduce((result, v) => [...result, ...v], [])
const listAddresses = addresses.map(a => a.address)
allAddresses = [...new Set([...allAddresses, ...listAddresses])]
const { txs } = await getTransactions(listAddresses)
const hasTransactions = txs.length > 0
transactions = [...transactions, ...txs.map(computeTransaction(allAddresses))]
lastAddress = hasTransactions ? getLastAddress(addresses, txs[0]) : lastAddress
if (hasTransactions) {
return nextPath(index + (gapLimit - 1))
}
return {
balance: transactions.reduce((result, v) => {
result += v.balance
return result
}, 0),
allAddresses,
transactions,
...(lastAddress !== null
? {
currentIndex: lastAddress.index,
address: lastAddress.address,
}
: {
currentIndex: 0,
address: getAddress({ type: 'external', index: 0 }).address,
}),
}
})
if (allAddresses.length === 0 && currentIndex > 0) {
for (let i = currentIndex; i--; ) {

30
src/internals/accounts/sync.js

@ -2,22 +2,30 @@
import { getAccount, getHDNode, networks } from 'helpers/btc'
const network = networks[1]
function syncAccount({ id, ...currentAccount }) {
const hdnode = getHDNode({ xpub58: id, network })
return getAccount({ hdnode, network, segwit: true, ...currentAccount }).then(account => ({
id,
...account,
}))
}
export default (send: Function) => ({
all: async ({ accounts }: { accounts: Array<Object> }) => {
const network = networks[1]
send('accounts.sync.progress', null, { kill: false })
const syncAccount = ({ id, currentIndex }) => {
const hdnode = getHDNode({ xpub58: id, network })
return getAccount({ currentIndex, hdnode, network, segwit: true }).then(account => ({
id,
...account,
}))
}
try {
const result = await Promise.all(accounts.map(syncAccount))
const result = await accounts.reduce(
(promise, account) =>
promise.then(async results => {
const result = await syncAccount(account)
return [...results, result]
}),
Promise.resolve([]),
)
send('accounts.sync.success', result)
} catch (err) {
send('accounts.sync.fail', err.stack || err)

Loading…
Cancel
Save