mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 15:04:50 +01:00
FIX: HD wallets not can handle small gaps in hierarchy (closes #388)
This commit is contained in:
parent
36e5aaa275
commit
d520da5cff
2 changed files with 25 additions and 12 deletions
|
@ -65,14 +65,11 @@ it('can create a Segwit HD (BIP49)', async function() {
|
|||
assert.strictEqual(hd._getInternalAddressByIndex(hd.next_free_change_address_index), freeChangeAddress);
|
||||
});
|
||||
|
||||
it.skip('HD (BIP49) can work with a gap', async function() {
|
||||
it('HD (BIP49) can work with a gap', async function() {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 240 * 1000;
|
||||
let hd = new HDSegwitP2SHWallet();
|
||||
hd._xpub = 'ypub6XRzrn3HB1tjhhvrHbk1vnXCecZEdXohGzCk3GXwwbDoJ3VBzZ34jNGWbC6WrS7idXrYjjXEzcPDX5VqnHEnuNf5VAXgLfSaytMkJ2rwVqy'; // has gap
|
||||
await hd.fetchBalance();
|
||||
console.log(hd.getBalance());
|
||||
console.log('hd.next_free_address_index = ', hd.next_free_address_index);
|
||||
console.log('hd.next_free_change_address_index = ', hd.next_free_change_address_index);
|
||||
|
||||
// for (let c = 0; c < 5; c++) {
|
||||
// console.log('internal', c, hd._getInternalAddressByIndex(c));
|
||||
|
@ -84,7 +81,6 @@ it.skip('HD (BIP49) can work with a gap', async function() {
|
|||
await hd.fetchTransactions();
|
||||
console.log('hd.transactions.length=', hd.transactions.length);
|
||||
assert.ok(hd.transactions.length >= 3);
|
||||
assert.ok(hd.next_free_address_index >= 4);
|
||||
});
|
||||
|
||||
it.skip('Segwit HD (BIP49) can batch fetch many txs', async function() {
|
||||
|
|
|
@ -19,6 +19,7 @@ export class AbstractHDWallet extends LegacyWallet {
|
|||
this._xpub = ''; // cache
|
||||
this.usedAddresses = [];
|
||||
this._address_to_wif_cache = {};
|
||||
this.gap_limit = 3;
|
||||
}
|
||||
|
||||
generate() {
|
||||
|
@ -347,8 +348,6 @@ export class AbstractHDWallet extends LegacyWallet {
|
|||
|
||||
async fetchBalance() {
|
||||
try {
|
||||
// doing binary search for last used externa address
|
||||
|
||||
let that = this;
|
||||
|
||||
// refactor me
|
||||
|
@ -371,8 +370,6 @@ export class AbstractHDWallet extends LegacyWallet {
|
|||
return binarySearchIterationForInternalAddress(index, maxUsedIndex, minUnusedIndex, depth + 1);
|
||||
}
|
||||
|
||||
this.next_free_change_address_index = await binarySearchIterationForInternalAddress(100);
|
||||
|
||||
// refactor me
|
||||
// eslint-disable-next-line
|
||||
async function binarySearchIterationForExternalAddress(index, maxUsedIndex = 0, minUnusedIndex = 100500100, depth = 0) {
|
||||
|
@ -393,14 +390,34 @@ export class AbstractHDWallet extends LegacyWallet {
|
|||
return binarySearchIterationForExternalAddress(index, maxUsedIndex, minUnusedIndex, depth + 1);
|
||||
}
|
||||
|
||||
this.next_free_address_index = await binarySearchIterationForExternalAddress(100);
|
||||
if (this.next_free_change_address_index === 0 && this.next_free_address_index === 0) {
|
||||
// assuming that this is freshly imported/created wallet, with no internal variables set
|
||||
// wild guess - its completely empty wallet:
|
||||
let completelyEmptyWallet = false;
|
||||
let txs = await BlueElectrum.getTransactionsByAddress(that._getInternalAddressByIndex(0));
|
||||
if (txs.length === 0) {
|
||||
let txs2 = await BlueElectrum.getTransactionsByAddress(that._getExternalAddressByIndex(0));
|
||||
if (txs2.length === 0) {
|
||||
// yep, completely empty wallet
|
||||
completelyEmptyWallet = true;
|
||||
}
|
||||
}
|
||||
|
||||
// wrong guess. will have to rescan
|
||||
if (!completelyEmptyWallet) {
|
||||
// so doing binary search for last used address:
|
||||
this.next_free_change_address_index = await binarySearchIterationForInternalAddress(100);
|
||||
this.next_free_address_index = await binarySearchIterationForExternalAddress(100);
|
||||
}
|
||||
}
|
||||
|
||||
this.usedAddresses = [];
|
||||
|
||||
// generating all involved addresses:
|
||||
for (let c = 0; c < this.next_free_address_index; c++) {
|
||||
for (let c = 0; c < this.next_free_address_index + this.gap_limit; c++) {
|
||||
this.usedAddresses.push(this._getExternalAddressByIndex(c));
|
||||
}
|
||||
for (let c = 0; c < this.next_free_change_address_index; c++) {
|
||||
for (let c = 0; c < this.next_free_change_address_index + this.gap_limit; c++) {
|
||||
this.usedAddresses.push(this._getInternalAddressByIndex(c));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue