Skip to content

Commit c543895

Browse files
committed
fix: transaction counter of a specific block; pagination cursor issue on lists with one element; fixed transactions order response based on sorting edges with database PK
1 parent f38ffcf commit c543895

File tree

14 files changed

+299
-272
lines changed

14 files changed

+299
-272
lines changed

indexer/src/kadena-server/repository/application/block-repository.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export default interface BlockRepository {
6060

6161
getTotalCountOfBlockEvents(blockHash: string): Promise<number>;
6262

63+
getTotalCountOfBlockTransactions(blockHash: string): Promise<number>;
64+
6365
getLatestBlocks(params: GetLatestBlocksParams): Promise<BlockOutput[]>;
6466

6567
getTransactionsOrderedByBlockDepth(

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,27 @@ export default class BlockDbRepository implements BlockRepository {
599599
return block?.transactionsCount || 0;
600600
}
601601

602+
/**
603+
* Counts the total number of transactions in a specific block
604+
*
605+
* This method performs a COUNT query to determine how many transactions
606+
* are associated to a particular block.
607+
*
608+
* @param blockHash - The hash of the block to count transactions for
609+
* @returns Promise resolving to the total count of transactions in the block
610+
*/
611+
async getTotalCountOfBlockTransactions(blockHash: string): Promise<number> {
612+
const { rows } = await rootPgPool.query(
613+
`SELECT COUNT(*) as "totalCount"
614+
FROM "Blocks" b
615+
JOIN "Transactions" t ON t."blockId" = b.id
616+
WHERE b.hash = $1`,
617+
[blockHash],
618+
);
619+
620+
return rows[0].totalCount ?? 0;
621+
}
622+
602623
/**
603624
* Retrieves the most recent blocks created after a specific timestamp
604625
*

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,21 @@ export default class TransactionDbRepository implements TransactionRepository {
334334
const { rows } = await rootPgPool.query(query, queryParams);
335335

336336
// Transform database rows into GraphQL-compatible edges with cursors
337-
const edges = rows.map(row => ({
338-
cursor: row.creationTime.toString(),
339-
node: transactionValidator.validate(row),
340-
}));
337+
const edges = rows
338+
.map(row => ({
339+
cursor: row.creationTime.toString(),
340+
node: transactionValidator.validate(row),
341+
}))
342+
.sort((a, b) => {
343+
// Primary sort is already done by DB query (creationTime DESC)
344+
// Add secondary sort by id for consistent ordering when creationTimes are equal
345+
const aNode = a.node as unknown as { id: string };
346+
const bNode = b.node as unknown as { id: string };
347+
if (a.cursor === b.cursor) {
348+
return aNode.id > bNode.id ? 1 : -1;
349+
}
350+
return 0; // Maintain existing order from DB for different creationTimes
351+
});
341352

342353
const pageInfo = getPageInfo({ edges, order, limit, after, before });
343354
return pageInfo;

indexer/src/kadena-server/repository/pagination.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export const getPageInfo = <T>({
115115
// that was fetched to determine if there are more pages
116116
const limit = (limitParam ?? DEFAULT_LIMIT) - LIMIT_NEXT_PAGE_CHECK;
117117

118-
// Case 1: No results found - return empty page info
118+
// Empty case: No results found - return empty page info
119119
if (length === 0) {
120120
return {
121121
pageInfo: {
@@ -128,23 +128,6 @@ export const getPageInfo = <T>({
128128
};
129129
}
130130

131-
// Case 2: Only a single result - simplify the logic for this case
132-
if (length === 1) {
133-
return {
134-
pageInfo: {
135-
// For a single result, both start and end cursor are the same
136-
startCursor: encodeCursor(edges[0].cursor),
137-
endCursor: encodeCursor(edges[0].cursor),
138-
// If 'before' exists, there might be more newer items (for backward pagination)
139-
hasNextPage: !!before,
140-
// If 'after' exists, there might be more older items (for forward pagination)
141-
hasPreviousPage: !!after,
142-
},
143-
edges,
144-
};
145-
}
146-
147-
// Case 3: Multiple results - compute page info based on sort order
148131
let hasNextPage = false;
149132
let hasPreviousPage = false;
150133
let startCursor = null;

indexer/src/kadena-server/resolvers/fields/block-transactions-connection/total-count-block-transactions-connection-resolver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const totalCountBlockTransactionsConnectionResolver: BlockTransactionsCon
2727
async (parent, _args, context) => {
2828
const { blockHash } = schema.parse(parent);
2929

30-
const total = await context.blockRepository.getTotalCountOfBlockEvents(blockHash);
30+
const total = await context.blockRepository.getTotalCountOfBlockTransactions(blockHash);
3131

3232
return total;
3333
};

indexer/tests/integration/fixtures/block/block.fixture.001.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const blockFixture001 = {
1515
},
1616
edges: [
1717
{
18-
cursor: '257165675',
18+
cursor: 'MjU3MTY1Njc1',
1919
node: {
2020
chainId: 10,
2121
height: 5370064,
@@ -71,7 +71,7 @@ export const blockFixture001 = {
7171
powHash: '00000000000000017af989466338f4c86bd3e2a9e6eb7860366fe377428b8bd7',
7272
target: 'WcVbkSM_1xf7DgJgoL6QKFKrX4SFcvxEEAAAAAAAAAA',
7373
transactions: {
74-
totalCount: 0,
74+
totalCount: 1,
7575
pageInfo: {
7676
endCursor: 'MTczMzU3MjgwMw==',
7777
hasNextPage: false,
@@ -80,7 +80,7 @@ export const blockFixture001 = {
8080
},
8181
edges: [
8282
{
83-
cursor: '1733572803',
83+
cursor: 'MTczMzU3MjgwMw==',
8484
node: {
8585
id: 'VHJhbnNhY3Rpb246WyJiNnBybXAzVkZIeE12cmR3VlpfREtiOGVvNW1vUEp2M1N3TkEwR0xwOEkwIiwiSWs1QmVVaG5MVGs1UlZaRk9XOXlMV0p0VlU1SFZIZHViR3d6TFRGdE5VMUVNaloyU1ZaWVprVklVbWNpIl0=',
8686
},

0 commit comments

Comments
 (0)