Skip to content

Commit

Permalink
fixup! feat(wallet): the wallet now only fetches UTXOs on tx history …
Browse files Browse the repository at this point in the history
…change
  • Loading branch information
AngelCastilloB committed Nov 15, 2024
1 parent 08301b5 commit 6244a8e
Showing 1 changed file with 49 additions and 47 deletions.
96 changes: 49 additions & 47 deletions packages/wallet/src/services/TransactionsTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,30 @@ const getLastTransactionsAtBlock = (
return txsFromSameBlock;
};

export const revertLastBlock = (
localTransactions: Cardano.HydratedTx[],
blockNo: Cardano.BlockNo,
rollback$: Subject<Cardano.HydratedTx>,
logger: Logger
) => {
const result = [...localTransactions];

while (result.length > 0) {
const lastKnownTx = result[result.length - 1];

if (lastKnownTx.blockHeader.blockNo === blockNo) {
logger.debug(`Transaction ${lastKnownTx.id} was rolled back`);

rollback$.next(lastKnownTx);
result.pop();
} else {
break;
}
}

return result;
};

const findIntersectionAndUpdateTxStore = ({
chainHistoryProvider,
logger,
Expand All @@ -148,12 +172,9 @@ const findIntersectionAndUpdateTxStore = ({
combinator: exhaustMap,
equals: transactionsEquals,
onFatalError,
// eslint-disable-next-line complexity
provider: async () => {
// eslint-disable-next-line no-constant-condition
while (true) {
let rollbackOccured = false;

const lastStoredTransaction: Cardano.HydratedTx | undefined = localTransactions[localTransactions.length - 1];

lastStoredTransaction &&
Expand All @@ -172,65 +193,46 @@ const findIntersectionAndUpdateTxStore = ({
lowerBound !== undefined && `since block ${lowerBound}`
);

// Fetching transactions from scratch, nothing else to do here.
if (lowerBound === undefined) {
localTransactions = newTransactions;
return localTransactions;
return newTransactions;
}

// If no transactions found from that block range, it means the last known block has been rolled back.
if (newTransactions.length === 0) {
// If no transactions found from that block range, it means the last known block has been rolled back.
while (localTransactions.length > 0) {
const lastKnownTx = localTransactions[localTransactions.length - 1];

if (lastKnownTx.blockHeader.blockNo === lowerBound) {
rollbackOccured = true;
logger.debug(`Transaction ${lastKnownTx.id} was rolled back`);
rollback$.next(lastKnownTx);
localTransactions.pop();
} else {
break;
}
}

localTransactions = revertLastBlock(localTransactions, lowerBound, rollback$, logger);
continue;
}

const localTxsFromSameBlock = getLastTransactionsAtBlock(localTransactions, lowerBound);
const firstSegmentOfNewTransactions = newTransactions.slice(0, localTxsFromSameBlock.length);

// Roll back transactions from this block not found in the result
for (const localTx of localTxsFromSameBlock) {
const txFound = newTransactions.find((tx) => tx.id === localTx.id);

if (!txFound) {
rollbackOccured = true;
logger.debug(`Transaction ${localTx.id} was rolled back`);
rollback$.next(localTx);
// The first segment of new transaction should match exactly (same txs and same order) our last know TXs. Otherwise
// roll them back and re-apply in new order.
const sameLength = localTxsFromSameBlock.length === firstSegmentOfNewTransactions.length;
const sameOrder =
sameLength && localTxsFromSameBlock.every((tx, index) => tx.id === firstSegmentOfNewTransactions[index].id);

const index = localTransactions.findLastIndex((tx) => tx.id === localTx.id);
if (!sameLength || !sameOrder) {
localTransactions = revertLastBlock(localTransactions, lowerBound, rollback$, logger);
localTransactions = [...localTransactions, ...newTransactions];
store.setAll(localTransactions);

if (index !== -1) {
localTransactions.splice(index, 1);
}
}
continue;
}

if (!rollbackOccured) {
const lastLocalTxs = localTransactions.slice(-newTransactions.length);

const areTransactionsSame =
lastLocalTxs.length === newTransactions.length &&
lastLocalTxs.every((tx, index) => tx.id === newTransactions[index].id);
// No rollbacks, if they overlap 100% do nothing, otherwise add the difference.
const areTransactionsSame =
newTransactions.length === localTxsFromSameBlock.length &&
localTxsFromSameBlock.every((tx, index) => tx.id === newTransactions[index].id);

if (!areTransactionsSame) {
// Remove overlapping transactions
localTransactions = localTransactions.slice(0, -localTxsFromSameBlock.length);
localTransactions = [...localTransactions, ...newTransactions];

store.setAll(localTransactions);
}

return localTransactions;
if (!areTransactionsSame) {
// Skip overlapping transactions to avoid duplicates
localTransactions = [...localTransactions, ...newTransactions.slice(localTxsFromSameBlock.length)];
store.setAll(localTransactions);
}

return localTransactions;
}
},
retryBackoffConfig,
Expand Down

0 comments on commit 6244a8e

Please sign in to comment.