Browse Source

FIX: large HD utxo fetch (closes #459)

feesheet
Overtorment 6 years ago
parent
commit
020cb8abf1
  1. 3
      HDWallet.test.js
  2. 66
      class/abstract-hd-wallet.js

3
HDWallet.test.js

@ -211,6 +211,9 @@ it('Segwit HD (BIP49) can fetch balance with many used addresses in hierarchy',
await hd.fetchUtxo();
assert.ok(hd.utxo.length > 0);
assert.ok(hd.utxo[0].txid);
assert.ok(hd.utxo[0].vout === 0);
assert.ok(hd.utxo[0].amount);
await hd.fetchTransactions();
assert.strictEqual(hd.getTransactions().length, 107);

66
class/abstract-hd-wallet.js

@ -429,27 +429,18 @@ export class AbstractHDWallet extends LegacyWallet {
}
}
/**
* @inheritDoc
*/
async fetchUtxo() {
async _fetchUtxoBatch(addresses) {
const api = new Frisbee({
baseURI: 'https://blockchain.info',
});
if (this.usedAddresses.length === 0) {
// just for any case, refresh balance (it refreshes internal `this.usedAddresses`)
await this.fetchBalance();
}
let addresses = this.usedAddresses.join('|');
addresses += '|' + this._getExternalAddressByIndex(this.next_free_address_index);
addresses += '|' + this._getInternalAddressByIndex(this.next_free_change_address_index);
addresses = addresses.join('|');
let utxos = [];
let response;
let uri;
try {
uri = 'https://blockchain.info' + '/unspent?active=' + addresses + '&limit=1000';
response = await api.get('/unspent?active=' + addresses + '&limit=1000');
// this endpoint does not support offset of some kind o_O
// so doing only one call
@ -469,10 +460,55 @@ export class AbstractHDWallet extends LegacyWallet {
utxos.push(unspent);
}
} catch (err) {
console.warn(err);
console.warn(err, { uri });
}
return utxos;
}
/**
* @inheritDoc
*/
async fetchUtxo() {
if (this.usedAddresses.length === 0) {
// just for any case, refresh balance (it refreshes internal `this.usedAddresses`)
await this.fetchBalance();
}
this.utxo = [];
let addresses = this.usedAddresses;
addresses.push(this._getExternalAddressByIndex(this.next_free_address_index));
addresses.push(this._getInternalAddressByIndex(this.next_free_change_address_index));
let duplicateUtxos = {};
let batch = [];
for (let addr of addresses) {
batch.push(addr);
if (batch.length >= 75) {
let utxos = await this._fetchUtxoBatch(batch);
for (let utxo of utxos) {
let key = utxo.txid + utxo.vout;
if (!duplicateUtxos[key]) {
this.utxo.push(utxo);
duplicateUtxos[key] = 1;
}
}
batch = [];
}
}
this.utxo = utxos;
// final batch
if (batch.length > 0) {
let utxos = await this._fetchUtxoBatch(batch);
for (let utxo of utxos) {
let key = utxo.txid + utxo.vout;
if (!duplicateUtxos[key]) {
this.utxo.push(utxo);
duplicateUtxos[key] = 1;
}
}
}
}
weOwnAddress(addr) {

Loading…
Cancel
Save