Skip to content
Draft
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
3 changes: 3 additions & 0 deletions cysync/src/store/database/helper/transaction/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export const getAllTxns = async (
andQuery.push({ $not: { status: Status.PENDING } });
}

// Omitting Discarded Txns by default
andQuery.push({ $not: { status: Status.DISCARDED } });

if (options.sinceDate) {
innerQuery.confirmed = { $gt: options.sinceDate };
delete options.sinceDate;
Expand Down
7 changes: 6 additions & 1 deletion cysync/src/store/database/helper/transaction/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export { convertToDisplayValue } from './misc';
export { insertFromFullTxn, prepareFromBlockbookTxn } from './insert';
export {
insertFromFullTxn,
prepareFromBlockbookTxn,
handleBumpedTxn,
clearTxnPayloads
} from './insert';
export { TxQuery, TxQueryOptions, getAllTxns, getTopBlock } from './get';
export { updateConfirmations } from './update';
69 changes: 59 additions & 10 deletions cysync/src/store/database/helper/transaction/insert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,20 @@ export const insertFromFullTxn = async (transaction: {
outputs
};

// Update the confirmations of txns with same hash
await transactionDb.findAndUpdate(
{ hash: txn.hash, walletId },
{
confirmations: newTxn.confirmations,
blockHeight: newTxn.blockHeight,
status: newTxn.status
}
);
await transactionDb.insert(newTxn);
if (existingTxns && existingTxns.length > 0) {
// Update the confirmations of txns with same hash
await transactionDb.findAndUpdate(
{ hash: txn.hash, walletId, slug: coinType },
{
confirmed: newTxn.confirmed,
confirmations: newTxn.confirmations,
blockHeight: newTxn.blockHeight,
status: newTxn.status
}
);
} else {
await transactionDb.insert(newTxn);
}
} else if (coin instanceof EthCoinData) {
// Derive address from Xpub (It'll always give a mixed case address with checksum)
const myAddress =
Expand Down Expand Up @@ -554,3 +558,48 @@ export const prepareFromBlockbookTxn = async (transaction: {
return [newTxn, feeTxn];
}
};

export const handleBumpedTxn = (t1: any) => {
const storedTxns = getTxnPayloads();
const tIndex = storedTxns.findIndex(async (t2: any) => {
return (
t1.address === t2.address &&
t1.coinType === t2.coinType &&
t1.txn.blockHeight === t2.txn.blockHeight &&
t1.txn.vout.find((out: any) => out.addresses.includes(t1.address))
.value ===
t2.txn.vout.find((out: any) => out.addresses.includes(t2.address)).value
);
});

if (tIndex !== -1) {
const oldTxnHash = storedTxns[tIndex].txn.txid;
transactionDb.findAndUpdate(
{ hash: oldTxnHash, status: Status.PENDING },
{ status: Status.DISCARDED }
);
storedTxns[tIndex] = t1;
storeTxnPayloads(storedTxns);
return true;
} else {
storedTxns.push(t1);
storeTxnPayloads(storedTxns);
return false;
}
};

const getTxnPayloads = () => {
const data = localStorage.getItem('txnPayloads');
if (data) return JSON.parse(data);
return [];
};

const storeTxnPayloads = (payloads: any) => {
localStorage.setItem('txnPayloads', JSON.stringify(payloads));
};

export const clearTxnPayloads = (slug: string) => {
const data = getTxnPayloads();
co.filter((payload: any) => payload.coinType !== slug);
storeTxnPayloads(data);
};
4 changes: 4 additions & 0 deletions cysync/src/store/provider/socketProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { deleteAllPortfolioCache } from '../../../utils/cache';
import logger from '../../../utils/logger';
import {
addressDb,
clearTxnPayloads,
coinDb,
handleBumpedTxn,
insertFromFullTxn,
prepareFromBlockbookTxn,
receiveAddressDb,
Expand Down Expand Up @@ -487,6 +489,7 @@ export const SocketProvider: React.FC = ({ children }) => {
try {
logger.info('Received txn from blockbookSocket', { payload });
if (payload && payload.coinType && payload.txn) {
handleBumpedTxn(payload);
const allAddresses = await getDetailsFromTxn(
payload.coinType,
payload.txn
Expand Down Expand Up @@ -566,6 +569,7 @@ export const SocketProvider: React.FC = ({ children }) => {
});
}
}
clearTxnPayloads(payload.coinType);
}
} else {
logger.warn('Receive new block hook does not have proper data', {
Expand Down
19 changes: 10 additions & 9 deletions cysync/src/store/provider/syncProvider/executors/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ export const processResponses = async (
newTxns.forEach(newTxn => transactionDbList.push(newTxn));
}

try {
await transactionDb.insertMany(transactionDbList);
} catch (error) {
// No need to retry if the inserting fails because it'll produce the same error.
logger.error(
`${CysyncError.TXN_INSERT_FAILED} Error while inserting transaction in DB : prepareFromBlockbookTxn`
);
logger.error(error);
}

// If there are more txs, return the last block height
if (
response.data.page &&
Expand All @@ -212,15 +222,6 @@ export const processResponses = async (
};
}
}
try {
await transactionDb.insertMany(transactionDbList);
} catch (error) {
// No need to retry if the inserting fails because it'll produce the same error.
logger.error(
`${CysyncError.TXN_INSERT_FAILED} Error while inserting transaction in DB : prepareFromBlockbookTxn`
);
logger.error(error);
}
return undefined;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/database