Skip to content

Commit 4a5447d

Browse files
committed
refactor: improved transactions count when using minHeight and maxHeight
1 parent eb3fa47 commit 4a5447d

File tree

1 file changed

+78
-64
lines changed

1 file changed

+78
-64
lines changed

indexer/src/kadena-server/repository/infra/repository/transaction-db-repository.ts

Lines changed: 78 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,41 @@ export default class TransactionDbRepository implements TransactionRepository {
540540
return totalCount;
541541
}
542542

543+
private getHeightChange(
544+
counters: { chainId: number; counter: number }[],
545+
minHeight: number | null,
546+
maxHeight: number | null,
547+
) {
548+
// If no height constraints, return the sum of all counters
549+
if (!minHeight && !maxHeight) {
550+
return counters.reduce((acc, curr) => acc + curr.counter, 0);
551+
}
552+
553+
let totalCount = 0;
554+
for (const { chainId, counter } of counters) {
555+
// Determine starting height for each chain
556+
const chainStartHeight = chainId >= 10 ? 852054 : 0;
557+
558+
// If no maxHeight provided, use counter - 1 (since height 0 is valid)
559+
const chainMaxHeight = maxHeight !== null ? maxHeight : counter - 1;
560+
561+
// Calculate the effective height range for this chain
562+
const effectiveMinHeight = Math.max(minHeight || 0, chainStartHeight);
563+
const effectiveMaxHeight = chainMaxHeight;
564+
565+
// If the range is invalid (min > max), skip this chain
566+
if (effectiveMinHeight > effectiveMaxHeight) {
567+
continue;
568+
}
569+
570+
// Calculate how many blocks are included in the range [effectiveMinHeight, effectiveMaxHeight]
571+
const includedBlocks = Math.max(0, effectiveMaxHeight - effectiveMinHeight + 1);
572+
573+
totalCount += includedBlocks;
574+
}
575+
576+
return totalCount;
577+
}
543578
/**
544579
* Counts transactions matching the specified filter parameters.
545580
* This method efficiently counts matching transactions without retrieving full data.
@@ -552,72 +587,53 @@ export default class TransactionDbRepository implements TransactionRepository {
552587
isCoinbase: isCoinbaseParam,
553588
chainId: chainIdParam,
554589
minimumDepth: minimumDepthParam,
590+
minHeight: minHeightParam,
591+
maxHeight: maxHeightParam,
555592
...rest
556593
} = params;
594+
557595
const hasNoOtherParams = Object.values(rest).every(v => v === undefined || v === null);
558596
if (hasNoOtherParams) {
559597
const query = `
560-
SELECT sum("canonicalTransactions") as "totalTransactionsCount", sum("canonicalBlocks") as "totalBlocksCount"
598+
SELECT "chainId", "canonicalTransactions" as "transactionsCount", "canonicalBlocks" as "blocksCount"
561599
FROM "Counters"
562-
${chainIdParam ? `WHERE "chainId" = $1` : ''}
563600
`;
564601

565-
const { rows } = await rootPgPool.query(query, chainIdParam ? [chainIdParam] : []);
566-
567-
const totalTransactionsCount = parseInt(rows?.[0]?.totalTransactionsCount ?? '0', 10);
568-
const totalBlocksCount = parseInt(rows?.[0]?.totalBlocksCount ?? '0', 10);
569-
const totalCount = totalTransactionsCount + (params.isCoinbase ? totalBlocksCount : 0);
602+
const { rows } = await rootPgPool.query(query);
603+
604+
const counters = rows
605+
.map(r => {
606+
const { chainId, transactionsCount, blocksCount } = r;
607+
const counter =
608+
parseInt(transactionsCount, 10) + (params.isCoinbase ? parseInt(blocksCount, 10) : 0);
609+
return {
610+
chainId,
611+
counter,
612+
};
613+
})
614+
.filter(c => (chainIdParam ? c.chainId.toString() === chainIdParam : true));
615+
616+
const counterConsideringHeight = this.getHeightChange(
617+
counters,
618+
minHeightParam ?? null,
619+
maxHeightParam ?? null,
620+
);
570621

571622
const depthDecrement = (minimumDepthParam ?? 0) * (isNullOrUndefined(chainIdParam) ? 20 : 1);
572-
return Math.max(totalCount - depthDecrement, 0);
573-
}
574-
575-
const {
576-
accountName: accountNameParam,
577-
fungibleName: fungibleNameParam,
578-
chainId: chainIdParamTwo,
579-
...rest2
580-
} = params;
581-
const hasNoOtherParams2 = Object.values(rest2).every(v => v === undefined || v === null);
582-
if (accountNameParam && fungibleNameParam && hasNoOtherParams2) {
583-
let query = `
584-
SELECT COUNT(*) as count
585-
FROM "Transactions" t
586-
JOIN "Events" e ON e."transactionId" = t.id
587-
WHERE t.sender = $1 AND e.module = $2
588-
`;
589-
590-
if (chainIdParamTwo) {
591-
query += `\nAND EXISTS (
592-
SELECT 1
593-
FROM "Blocks" b
594-
WHERE b.id = t."blockId"
595-
AND b."chainId" = $3
596-
AND b.canonical = true
597-
)`;
598-
}
599-
600-
const { rows: countResult } = await rootPgPool.query(query, [
601-
accountNameParam,
602-
fungibleNameParam,
603-
chainIdParamTwo,
604-
]);
605-
606-
const totalCount = parseInt(countResult[0].count, 10);
607-
const depthDecrement =
608-
(minimumDepthParam ?? 0) * (isNullOrUndefined(chainIdParamTwo) ? 20 : 1);
609-
return Math.max(totalCount - depthDecrement, 0);
623+
return counterConsideringHeight - depthDecrement;
610624
}
611625

612626
const {
613627
blockHash,
614628
accountName,
615-
chainId,
616629
requestKey,
617630
fungibleName,
618-
minHeight,
619-
maxHeight,
620631
hasTokenId,
632+
chainId,
633+
isCoinbase,
634+
maxHeight,
635+
minHeight,
636+
minimumDepth,
621637
} = params;
622638
const transactionsParams: (string | number)[] = [];
623639
const blockParams: (string | number | boolean)[] = [];
@@ -630,18 +646,12 @@ export default class TransactionDbRepository implements TransactionRepository {
630646
transactionsParams.push(accountName);
631647
const op = localOperator(transactionsParams.length);
632648
transactionsConditions += `${op} t.sender = $${transactionsParams.length}`;
633-
} else if (!isCoinbaseParam) {
649+
} else if (!isCoinbase) {
634650
transactionsParams.push('coinbase');
635651
const op = localOperator(transactionsParams.length);
636652
transactionsConditions += `${op} t.sender != $${transactionsParams.length}`;
637653
}
638654

639-
if (requestKey) {
640-
transactionsParams.push(requestKey);
641-
const op = localOperator(transactionsParams.length);
642-
transactionsConditions += `${op} t."requestkey" = $${transactionsParams.length}`;
643-
}
644-
645655
if (fungibleName) {
646656
transactionsParams.push(fungibleName);
647657
const op = localOperator(transactionsParams.length);
@@ -655,19 +665,23 @@ export default class TransactionDbRepository implements TransactionRepository {
655665
)`;
656666
}
657667

658-
if (accountName && hasTokenId) {
659-
transactionsParams.push(accountName);
668+
if (hasTokenId) {
660669
const op = localOperator(transactionsParams.length);
661670
transactionsConditions += `
662671
${op} EXISTS
663672
(
664673
SELECT 1
665674
FROM "Transfers" t
666-
WHERE t."from_acct" = $${transactionsParams.length}
667-
AND t."hasTokenId" = true
675+
WHERE t."hasTokenId" = true
668676
)`;
669677
}
670678

679+
if (requestKey) {
680+
transactionsParams.push(requestKey);
681+
const op = localOperator(transactionsParams.length);
682+
transactionsConditions += `${op} t."requestkey" = $${transactionsParams.length}`;
683+
}
684+
671685
const paramsOffset = transactionsParams.length;
672686

673687
blockParams.push(true);
@@ -698,16 +712,16 @@ export default class TransactionDbRepository implements TransactionRepository {
698712
}
699713

700714
const totalCountQuery = `
701-
WITH filtered_transactions AS (
702-
SELECT id, "blockId"
703-
FROM "Transactions" t
704-
${transactionsConditions}
715+
WITH filtered_transactions AS (
716+
SELECT id, "blockId"
717+
FROM "Transactions" t
718+
${transactionsConditions}
705719
)
706720
SELECT COUNT(*) as count
707721
FROM filtered_transactions t
708722
${blocksConditions ? `JOIN "Blocks" b ON b.id = t."blockId"` : ''}
709723
${blocksConditions}
710-
`;
724+
`;
711725

712726
const { rows: countResult } = await rootPgPool.query(totalCountQuery, [
713727
...transactionsParams,

0 commit comments

Comments
 (0)