Skip to content

Commit 8bdd0eb

Browse files
authored
Merge pull request #413 from hack-a-chain-software/transfers-pagination
fix: added the transfer database ID to make the ORDER BY deterministic in the transfers query
2 parents 7c056d3 + 735d8cf commit 8bdd0eb

File tree

13 files changed

+3971
-473
lines changed

13 files changed

+3971
-473
lines changed

.github/workflows/indexer.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,3 @@ jobs:
2424
- name: Install dependencies
2525
run: yarn install
2626
working-directory: ./indexer
27-
28-
- name: Build
29-
run: tsc
30-
working-directory: ./indexer

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

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,19 @@ export default class TransferDbRepository implements TransferRepository {
9191
}
9292

9393
if (after) {
94-
queryParams.push(after);
94+
const [creationTime, id] = after.split(':');
95+
queryParams.push(creationTime);
9596
const op = operator(queryParams.length);
96-
conditions += `\n${op} transfers.id < $${queryParams.length}`;
97+
queryParams.push(id);
98+
conditions += `\n${op} (t.creationtime, t.id) < ($${queryParams.length - 1}, $${queryParams.length})`;
9799
}
98100

99101
if (before) {
100-
queryParams.push(before);
102+
const [creationTime, id] = before.split(':');
103+
queryParams.push(creationTime);
101104
const op = operator(queryParams.length);
102-
conditions += `\n${op} transfers.id > $${queryParams.length}`;
105+
queryParams.push(id);
106+
conditions += `\n${op} (t.creationtime, t.id) > ($${queryParams.length - 1}, $${queryParams.length})`;
103107
}
104108

105109
if (chainId) {
@@ -155,7 +159,7 @@ export default class TransferDbRepository implements TransferRepository {
155159
join "Transfers" transfers on transfers."transactionId" = t.id
156160
left join "TransactionDetails" td on t.id = td."transactionId"
157161
${conditions}
158-
ORDER BY transfers.id ${order}
162+
ORDER BY t."creationtime" ${order}, transfers.id ${order}
159163
LIMIT $1
160164
`;
161165
} else if (requestKey) {
@@ -185,47 +189,11 @@ export default class TransferDbRepository implements TransferRepository {
185189
join "Transfers" transfers on transfers."transactionId" = t.id
186190
left join "TransactionDetails" td on t.id = td."transactionId"
187191
${conditions}
188-
ORDER BY transfers.id ${order}
189-
LIMIT $1
190-
`;
191-
} else if (accountName) {
192-
query = `
193-
WITH filtered_transfers AS (
194-
SELECT id, amount, "transactionId", "from_acct", "to_acct", modulename, modulehash, requestkey, "orderIndex"
195-
FROM "Transfers" transfers
196-
${conditions}
197-
ORDER BY transfers.id ${order}
198-
LIMIT ALL
199-
)
200-
select transfers.id as id,
201-
transfers.amount as "transferAmount",
202-
t."chainId" as "chainId",
203-
t."creationtime" as "creationTime",
204-
t.id as "transactionId",
205-
b.height as "height",
206-
b.hash as "blockHash",
207-
transfers."from_acct" as "senderAccount",
208-
transfers."to_acct" as "receiverAccount",
209-
transfers.modulename as "moduleName",
210-
transfers.modulehash as "moduleHash",
211-
transfers.requestkey as "requestKey",
212-
transfers."orderIndex" as "orderIndex",
213-
td.pactid as "pactId"
214-
from filtered_transfers transfers
215-
join "Transactions" t on t.id = transfers."transactionId"
216-
join "Blocks" b on b."id" = t."blockId"
217-
left join "TransactionDetails" td on t.id = td."transactionId"
192+
ORDER BY t."creationtime" ${order}, transfers.id ${order}
218193
LIMIT $1
219194
`;
220195
} else {
221196
query = `
222-
WITH filtered_transfers AS (
223-
SELECT id, amount, "transactionId", "from_acct", "to_acct", modulename, modulehash, requestkey, "orderIndex"
224-
FROM "Transfers" transfers
225-
${conditions}
226-
ORDER BY transfers.id ${order}
227-
LIMIT $1
228-
)
229197
select transfers.id as id,
230198
transfers.amount as "transferAmount",
231199
t."chainId" as "chainId",
@@ -240,17 +208,20 @@ export default class TransferDbRepository implements TransferRepository {
240208
transfers.requestkey as "requestKey",
241209
transfers."orderIndex" as "orderIndex",
242210
td.pactid as "pactId"
243-
from filtered_transfers transfers
211+
from "Transfers" transfers
244212
join "Transactions" t on t.id = transfers."transactionId"
245213
join "Blocks" b on b."id" = t."blockId"
246214
left join "TransactionDetails" td on t.id = td."transactionId"
215+
${conditions}
216+
ORDER BY t."creationtime" ${order}, transfers.id ${order}
217+
LIMIT $1
247218
`;
248219
}
249220

250221
const { rows } = await rootPgPool.query(query, queryParams);
251222

252223
const edges = rows.map(row => ({
253-
cursor: row.id.toString(),
224+
cursor: `${row.creationTime.toString()}:${row.id.toString()}`,
254225
node: transferSchemaValidator.validate(row),
255226
}));
256227

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

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,53 @@ export const transfersFixture001 = {
22
data: {
33
transfers: {
44
totalCount: 2,
5+
pageInfo: {
6+
endCursor: 'MTczNjcxMTA4NDo1ODI3MDQ3',
7+
hasNextPage: false,
8+
hasPreviousPage: false,
9+
startCursor: 'MTczNjcxMTA4NDo1ODI3MDQ4',
10+
},
511
edges: [
612
{
13+
cursor: 'MTczNjcxMTA4NDo1ODI3MDQ4',
714
node: {
815
amount: '34',
16+
block: {
17+
chainId: 1,
18+
},
19+
creationTime: '2025-01-12T19:44:44.000Z',
20+
crossChainTransfer: null,
21+
id: 'VHJhbnNmZXI6WyIwY0tsamlGVlZvbHNhT0hkWWRxLUpSbGJHN0d6WXFfWThfTjFKbjd0UEhZIiwiMSIsIjEiLCI4U1pxZm16cXdGb2ZZVUoyd25NRTBPLS0xSHZlUWtYSDdJZGtHM2JLWjBZIiwiUk54b05DY1FyaUVaVTNwX3FMU2lKQW83QmktMC1PZTdOa2prUEZPS3I3MCJd',
22+
moduleHash: '8SZqfmzqwFofYUJ2wnME0O--1HveQkXH7IdkG3bKZ0Y',
23+
moduleName: 'n_ebe54249b2e9d68f5060961f3c419f8288d18dc2.unitt',
24+
orderIndex: 1,
925
receiverAccount: 'k:7577a017eab7067e194fea639dae351406bc139425c7a170ceb4026f829b0816',
26+
requestKey: 'RNxoNCcQriEZU3p_qLSiJAo7Bi-0-Oe7NkjkPFOKr70',
1027
senderAccount: 'ef46137232f1cb9acebf717f94a5a9083e96db16957da79ed0d1df29b0bb4ff8',
11-
moduleName: 'n_ebe54249b2e9d68f5060961f3c419f8288d18dc2.unitt',
28+
transaction: {
29+
id: 'VHJhbnNhY3Rpb246WyIwY0tsamlGVlZvbHNhT0hkWWRxLUpSbGJHN0d6WXFfWThfTjFKbjd0UEhZIiwiUk54b05DY1FyaUVaVTNwX3FMU2lKQW83QmktMC1PZTdOa2prUEZPS3I3MCJd',
30+
},
1231
},
1332
},
1433
{
34+
cursor: 'MTczNjcxMTA4NDo1ODI3MDQ3',
1535
node: {
1636
amount: '0.001766',
37+
block: {
38+
chainId: 1,
39+
},
40+
creationTime: '2025-01-12T19:44:44.000Z',
41+
crossChainTransfer: null,
42+
id: 'VHJhbnNmZXI6WyIwY0tsamlGVlZvbHNhT0hkWWRxLUpSbGJHN0d6WXFfWThfTjFKbjd0UEhZIiwiMSIsIjAiLCJrbEZrckxmcHlMVy1NM3hqVlBTZHFYRU1neFBQSmliUnRfRDZxaUJ3czZzIiwiUk54b05DY1FyaUVaVTNwX3FMU2lKQW83QmktMC1PZTdOa2prUEZPS3I3MCJd',
43+
moduleHash: 'klFkrLfpyLW-M3xjVPSdqXEMgxPPJibRt_D6qiBws6s',
44+
moduleName: 'coin',
45+
orderIndex: 0,
1746
receiverAccount: 'k:e7f7130f359fb1f8c87873bf858a0e9cbc3c1059f62ae715ec72e760b055e9f3',
47+
requestKey: 'RNxoNCcQriEZU3p_qLSiJAo7Bi-0-Oe7NkjkPFOKr70',
1848
senderAccount: 'k:c55bf5b9f84c33616c31806402f66576b4e59ae4b90830636e38c746a44069fc',
19-
moduleName: 'coin',
49+
transaction: {
50+
id: 'VHJhbnNhY3Rpb246WyIwY0tsamlGVlZvbHNhT0hkWWRxLUpSbGJHN0d6WXFfWThfTjFKbjd0UEhZIiwiUk54b05DY1FyaUVaVTNwX3FMU2lKQW83QmktMC1PZTdOa2prUEZPS3I3MCJd',
51+
},
2052
},
2153
},
2254
],

0 commit comments

Comments
 (0)