Skip to content
This repository has been archived by the owner on Jan 12, 2022. It is now read-only.

fix: comportement on new address with existing transaction in store #147

Merged
merged 4 commits into from
Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 2 additions & 49 deletions src/plugins/Workers/BIP44Worker/ensureEnoughAddress.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,9 @@
const { BIP44_ADDRESS_GAP, WALLET_TYPES } = require('../../../CONSTANTS');
const is = require('../../../utils/is');

const isContiguousPath = (currPath, prevPath) => {
if (is.undef(currPath)) return false;
const splitedCurrPath = currPath.split('/');
const currIndex = parseInt(splitedCurrPath[5], 10);
if (is.undef(prevPath)) {
if (currIndex !== 0) return false;
return true;
}
const splitedPrevPath = prevPath.split('/');
const prevIndex = parseInt(splitedPrevPath[5], 10);
if (prevIndex !== currIndex - 1) return false;
return true;
};
const getMissingIndexes = (paths, fromOrigin = true) => {
if (!is.arr(paths)) return false;

let sortedIndexes = [];

paths.forEach((path) => {
const splitedPath = path.split('/');
const index = parseInt(splitedPath[5], 10);
sortedIndexes.push(index);
});

sortedIndexes = sortedIndexes.sort((a, b) => a - b);

let missingIndex = sortedIndexes.reduce((acc, cur, ind, arr) => {
const diff = cur - arr[ind - 1];
if (diff > 1) {
let i = 1;
while (i < diff) {
acc.push(arr[ind - 1] + i);
i += 1;
}
}
return acc;
}, []);
const getMissingIndexes = require('./utils/getMissingIndexes');
const isContiguousPath = require('./utils/isContiguousPath');

// Will fix missing index before our first known indexes
if (fromOrigin) {
if (sortedIndexes[0] > 0) {
for (let i = sortedIndexes[0] - 1; i >= 0; i -= 1) {
missingIndex.push(i);
}
}
}

missingIndex = missingIndex.sort((a, b) => a - b);
return missingIndex;
};
module.exports = function ensureEnoughAddress() {
let generated = 0;
let unusedAddress = 0;
Expand Down
39 changes: 39 additions & 0 deletions src/plugins/Workers/BIP44Worker/utils/getMissingIndexes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const is = require('../../../../utils/is');

module.exports = function getMissingIndexes(paths, fromOrigin = true) {
if (!is.arr(paths)) return false;

let sortedIndexes = [];

paths.forEach((path) => {
const splitedPath = path.split('/');
const index = parseInt(splitedPath[5], 10);
sortedIndexes.push(index);
});

sortedIndexes = sortedIndexes.sort((a, b) => a - b);

let missingIndex = sortedIndexes.reduce((acc, cur, ind, arr) => {
const diff = cur - arr[ind - 1];
if (diff > 1) {
let i = 1;
while (i < diff) {
acc.push(arr[ind - 1] + i);
i += 1;
}
}
return acc;
}, []);

// Will fix missing index before our first known indexes
if (fromOrigin) {
if (sortedIndexes[0] > 0) {
for (let i = sortedIndexes[0] - 1; i >= 0; i -= 1) {
missingIndex.push(i);
}
}
}

missingIndex = missingIndex.sort((a, b) => a - b);
return missingIndex;
};
15 changes: 15 additions & 0 deletions src/plugins/Workers/BIP44Worker/utils/isContiguousPath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const is = require('../../../../utils/is');

module.exports = function isContiguousPath(currPath, prevPath) {
if (is.undef(currPath)) return false;

const splitedCurrPath = currPath.split('/');
const currIndex = parseInt(splitedCurrPath[5], 10);

if (is.undef(prevPath)) {
return currIndex === 0;
}
const splitedPrevPath = prevPath.split('/');
const prevIndex = parseInt(splitedPrevPath[5], 10);
return prevIndex === currIndex - 1;
};
26 changes: 20 additions & 6 deletions src/types/Storage/methods/importTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ const importTransaction = function importTransaction(transaction) {

let hasUpdateStorage = false;
let outputIndex = -1;
const processedAddressesForTx = [];

if (transactions[transaction.hash]) {
return;
// If we already had this transaction locally, we won't add it again,
// but we still need to continue processing it as we might have new
// address generated (on BIP44 wallets) since the first checkup.
if (!transactions[transaction.hash]) {
transactions[transaction.hash] = transaction;
}

transactions[transaction.hash] = transaction;

[...inputs, ...outputs].forEach((element) => {
[...inputs, ...outputs].forEach((element, elementIndex) => {
const isOutput = (element instanceof Output);
if (isOutput) outputIndex += 1;

Expand All @@ -33,10 +35,22 @@ const importTransaction = function importTransaction(transaction) {
const addressObject = store.wallets[walletId].addresses[type][path];
if (!addressObject.used) addressObject.used = true;

if (!addressObject.transactions.includes(transaction.hash)) {
if (elementIndex === 0) {
// If the transactions has already been processed in a previous insertion,
// we can skip the processing now
if (addressObject.transactions.includes(transaction.hash)) {
// We mark it as already processed
processedAddressesForTx.push(addressObject.address);
return;
}
addressObject.transactions.push(transaction.hash);
hasUpdateStorage = true;
}
// If mark as already procesed on first run, skipping.
if (processedAddressesForTx.includes(addressObject.address)) {
return;
}

if (!isOutput) {
const vin = element;
const utxoKey = `${vin.prevTxId.toString('hex')}-${vin.outputIndex}`;
Expand Down