Browse Source

optimize /wallet endpoint

umbrel
kenshin-samourai 4 years ago
parent
commit
37bf6effd5
  1. 9
      lib/wallet/address-info.js
  2. 68
      lib/wallet/hd-account-info.js
  3. 16
      lib/wallet/wallet-info.js
  4. 81
      lib/wallet/wallet-service.js

9
lib/wallet/address-info.js

@ -38,10 +38,19 @@ class AddressInfo {
* @returns {Promise}
*/
async loadInfo() {
return Promise.all([
this._loadBalance(),
this._loadNbTransactions()
])
}
async _loadBalance() {
const balance = await db.getAddressBalance(this.address)
if (balance !== null)
this.finalBalance = balance
}
async _loadNbTransactions() {
const nbTxs = await db.getAddressNbTransactions(this.address)
if (nbTxs !== null)
this.nTx = nbTxs

68
lib/wallet/hd-account-info.js

@ -67,38 +67,50 @@ class HdAccountInfo {
*/
async loadInfo() {
try {
const id = await db.getHDAccountId(this.xpub)
//if (id == null) return false
const account = await db.getHDAccount(this.xpub)
this.created = account.hdCreated
this.derivation = hdaHelper.typeString(account.hdType)
this.tracked = true
this.finalBalance = await db.getHDAccountBalance(this.xpub)
const unusedIdx = await db.getHDAccountNextUnusedIndices(this.xpub)
this.accountIndex = unusedIdx[0]
this.changeIndex = unusedIdx[1]
await Promise.all([
this._loadDerivationInfo(),
this._loadBalance(),
this._loadUnusedIndices(),
this._loadDerivedIndices(),
this._loadNbTransactions(),
])
return true
} catch(e) {
return false
}
}
const derivedIdx = await db.getHDAccountDerivedIndices(this.xpub)
this.accountDerivedIndex = derivedIdx[0]
this.changeDerivedIndex = derivedIdx[1]
async _loadDerivationInfo() {
const account = await db.getHDAccount(this.xpub)
this.created = account.hdCreated
this.derivation = hdaHelper.typeString(account.hdType)
this.tracked = true
const node = hdaHelper.getNode(this.xpub)
const index = node[2].index
const threshold = Math.pow(2,31)
const hardened = (index >= threshold)
this.account = hardened ? (index - threshold) : index
this.depth = node[2].depth
}
this.nTx = await db.getHDAccountNbTransactions(this.xpub)
async _loadBalance() {
this.finalBalance = await db.getHDAccountBalance(this.xpub)
}
const node = hdaHelper.getNode(this.xpub)
const index = node[2].index
const threshold = Math.pow(2,31)
const hardened = (index >= threshold)
this.account = hardened ? (index - threshold) : index
this.depth = node[2].depth
async _loadUnusedIndices() {
const unusedIdx = await db.getHDAccountNextUnusedIndices(this.xpub)
this.accountIndex = unusedIdx[0]
this.changeIndex = unusedIdx[1]
}
return true
async _loadDerivedIndices() {
const derivedIdx = await db.getHDAccountDerivedIndices(this.xpub)
this.accountDerivedIndex = derivedIdx[0]
this.changeDerivedIndex = derivedIdx[1]
}
} catch(e) {
return false
}
async _loadNbTransactions() {
this.nTx = await db.getHDAccountNbTransactions(this.xpub)
}
/**
@ -111,7 +123,7 @@ class HdAccountInfo {
const utxos = await db.getHDAccountUnspentOutputs(this.xpub)
for (let utxo of utxos) {
const conf =
const conf =
(utxo.blockHeight == null)
? 0
: (rpcLatestBlock.height - utxo.blockHeight + 1)

16
lib/wallet/wallet-info.js

@ -49,10 +49,10 @@ class WalletInfo {
/**
* Ensure hd accounts exist in database
* @returns {Promise}
* @returns {Promise}
*/
async ensureHdAccounts() {
return util.seriesCall(this.entities.xpubs, async xpub => {
return util.parallelCall(this.entities.xpubs, async xpub => {
const hdaInfo = new HdAccountInfo(xpub)
return hdaInfo.ensureHdAccount()
})
@ -63,7 +63,7 @@ class WalletInfo {
* @returns {Promise}
*/
async loadHdAccountsInfo() {
return util.seriesCall(this.entities.xpubs, async xpub => {
return util.parallelCall(this.entities.xpubs, async xpub => {
const hdaInfo = new HdAccountInfo(xpub)
await hdaInfo.loadInfo()
this.wallet.finalBalance += hdaInfo.finalBalance
@ -77,7 +77,7 @@ class WalletInfo {
*/
async ensureAddresses() {
const importAddrs = []
const addrIdMap = await db.getAddressesIds(this.entities.addrs)
for (let addr of this.entities.addrs) {
@ -113,7 +113,7 @@ class WalletInfo {
* @returns {Promise}
*/
async loadAddressesInfo() {
return util.seriesCall(this.entities.addrs, async address => {
return util.parallelCall(this.entities.addrs, async address => {
const addrInfo = new AddressInfo(address)
await addrInfo.loadInfo()
this.wallet.finalBalance += addrInfo.finalBalance
@ -125,7 +125,7 @@ class WalletInfo {
* Loads a partial list of transactions for this wallet
* @param {integer} page - page index
* @param {integer} count - number of transactions per page
* @param {boolean} txBalance - True if past wallet balance
* @param {boolean} txBalance - True if past wallet balance
* should be computed for each transaction
* @returns {Promise}
*/
@ -166,7 +166,7 @@ class WalletInfo {
* @returns {Promise}
*/
async loadFeesInfo() {
this.info.fees = await rpcFees.getFees()
this.info.fees = await rpcFees.getFees()
}
/**
@ -175,7 +175,7 @@ class WalletInfo {
*/
async loadUtxos() {
// Load the utxos for the hd accounts
await util.seriesCall(this.entities.xpubs, async xpub => {
await util.parallelCall(this.entities.xpubs, async xpub => {
const hdaInfo = new HdAccountInfo(xpub)
const utxos = await hdaInfo.loadUtxos()
for (let utxo of utxos)

81
lib/wallet/wallet-service.js

@ -51,37 +51,53 @@ class WalletService {
const walletInfo = new WalletInfo(active)
try {
// Add the new xpubs
await util.seriesCall(legacy.xpubs, this._newBIP44)
await util.seriesCall(bip49.xpubs, this._newBIP49)
await util.seriesCall(bip84.xpubs, this._newBIP84)
// Load hd accounts info
await walletInfo.ensureHdAccounts()
await walletInfo.loadHdAccountsInfo()
// Add the new addresses
await db.addAddresses(legacy.addrs)
await db.addAddresses(bip49.addrs)
await db.addAddresses(bip84.addrs)
await db.addAddresses(pubkeys.addrs)
// Ensure addresses exist
await walletInfo.ensureAddresses()
await Promise.all([
// Add the new xpubs
util.parallelCall(legacy.xpubs, this._newBIP44),
util.parallelCall(bip49.xpubs, this._newBIP49),
util.parallelCall(bip84.xpubs, this._newBIP84),
// Add the new addresses
db.addAddresses(legacy.addrs),
db.addAddresses(bip49.addrs),
db.addAddresses(bip84.addrs),
db.addAddresses(pubkeys.addrs),
])
// Ensure hd accounts and addresses exist
await Promise.all([
walletInfo.ensureHdAccounts(),
walletInfo.ensureAddresses(),
])
// Force import of addresses associated to paynyms
// if dojo relies on a local index
if (keys.indexer.active != 'third_party_explorer')
await this._forceEnsureAddressesForActivePubkeys(active)
// Filter the addresses
await walletInfo.filterAddresses()
// Load the utxos
await walletInfo.loadUtxos()
// Load the addresses
await walletInfo.loadAddressesInfo()
// Load the most recent transactions
await walletInfo.loadTransactions(0, null, true)
// Load feerates
await walletInfo.loadFeesInfo()
// Load wallet information
await Promise.all([
// Load the hd accounts,
walletInfo.loadHdAccountsInfo(),
// Load the utxos
walletInfo.loadUtxos(),
// Load the addresses
walletInfo.loadAddressesInfo(),
// Load the most recent transactions
walletInfo.loadTransactions(0, null, true),
// Load feerates
walletInfo.loadFeesInfo(),
])
// Postprocessing
await walletInfo.postProcessAddresses()
await walletInfo.postProcessHdAccounts()
await Promise.all([
walletInfo.postProcessAddresses(),
walletInfo.postProcessHdAccounts(),
])
// Format the result
return this._formatGetFullWalletInfoResult(walletInfo)
@ -250,7 +266,7 @@ class WalletService {
return ret
} catch(e) {
Logger.error(e, 'WalletService.getWalletUtxos()')
Logger.error(e, 'WalletService.getWalletUtxos()')
return Promise.reject({status: 'error', error: 'internal server error'})
}
}
@ -280,20 +296,25 @@ class WalletService {
try {
// Filter the addresses
await walletInfo.filterAddresses()
// Load the number of transactions
await walletInfo.loadNbTransactions()
// Load the requested page of transactions
await walletInfo.loadTransactions(page, count, false)
await Promise.all([
// Load the number of transactions
walletInfo.loadNbTransactions(),
// Load the requested page of transactions
walletInfo.loadTransactions(page, count, false),
])
// Postprocessing
await walletInfo.postProcessAddresses()
await walletInfo.postProcessHdAccounts()
// Format the result
ret.n_tx = walletInfo.nTx
ret.txs = walletInfo.txs
return ret
} catch(e) {
Logger.error(e, 'WalletService.getWalletTransactions()')
Logger.error(e, 'WalletService.getWalletTransactions()')
return Promise.reject({status:'error', error:'internal server error'})
}
}

Loading…
Cancel
Save