Browse Source

Merge pull request #56 from loeck/master

Make getAsyncAddress for limit CPU usage
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
3927f8ed19
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  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 getLastAddress = (addresses, txs) => {
const txsAddresses = [...txs.inputs.map(tx => tx.prev_out.addr), ...txs.out.map(tx => tx.addr)] 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)) || { const lastAddress = addresses.reverse().find(a => txsAddresses.includes(a.address)) || {
@ -110,48 +113,53 @@ export async function getAccount({
} }
const nextPath = (index = 0) => const nextPath = (index = 0) =>
Promise.all( Array.from(new Array(gapLimit).keys())
Array.from(new Array(gapLimit).keys()).map(v => .reduce(
Promise.all([ (promise, v) =>
getAddress({ type: 'external', index: v + index }), promise.then(async results => {
getAddress({ type: 'internal', index: v + index }), const result = await Promise.all([
]), getAsyncAddress({ type: 'external', index: v + index }),
), getAsyncAddress({ type: 'internal', index: v + index }),
).then(async results => { ])
const addresses = results.reduce((result, v) => [...result, ...v], []) return [...results, result]
const listAddresses = addresses.map(a => a.address) }),
Promise.resolve([]),
allAddresses = [...new Set([...allAddresses, ...listAddresses])] )
.then(async results => {
const { txs } = await getTransactions(listAddresses) const addresses = results.reduce((result, v) => [...result, ...v], [])
const listAddresses = addresses.map(a => a.address)
const hasTransactions = txs.length > 0
allAddresses = [...new Set([...allAddresses, ...listAddresses])]
transactions = [...transactions, ...txs.map(computeTransaction(allAddresses))]
lastAddress = hasTransactions ? getLastAddress(addresses, txs[0]) : lastAddress const { txs } = await getTransactions(listAddresses)
if (hasTransactions) { const hasTransactions = txs.length > 0
return nextPath(index + (gapLimit - 1))
} transactions = [...transactions, ...txs.map(computeTransaction(allAddresses))]
lastAddress = hasTransactions ? getLastAddress(addresses, txs[0]) : lastAddress
return {
balance: transactions.reduce((result, v) => { if (hasTransactions) {
result += v.balance return nextPath(index + (gapLimit - 1))
return result }
}, 0),
allAddresses, return {
transactions, balance: transactions.reduce((result, v) => {
...(lastAddress !== null result += v.balance
? { return result
currentIndex: lastAddress.index, }, 0),
address: lastAddress.address, allAddresses,
} transactions,
: { ...(lastAddress !== null
currentIndex: 0, ? {
address: getAddress({ type: 'external', index: 0 }).address, currentIndex: lastAddress.index,
}), address: lastAddress.address,
} }
}) : {
currentIndex: 0,
address: getAddress({ type: 'external', index: 0 }).address,
}),
}
})
if (allAddresses.length === 0 && currentIndex > 0) { if (allAddresses.length === 0 && currentIndex > 0) {
for (let i = currentIndex; i--; ) { for (let i = currentIndex; i--; ) {

30
src/internals/accounts/sync.js

@ -2,22 +2,30 @@
import { getAccount, getHDNode, networks } from 'helpers/btc' 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) => ({ export default (send: Function) => ({
all: async ({ accounts }: { accounts: Array<Object> }) => { all: async ({ accounts }: { accounts: Array<Object> }) => {
const network = networks[1]
send('accounts.sync.progress', null, { kill: false }) 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 { 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) send('accounts.sync.success', result)
} catch (err) { } catch (err) {
send('accounts.sync.fail', err.stack || err) send('accounts.sync.fail', err.stack || err)

Loading…
Cancel
Save