44 * This class encapsulates the complex logic for constructing SQL queries
55 * to retrieve transactions from the database with various filtering criteria.
66 */
7+ import { isNullOrUndefined } from '@/utils/helpers' ;
78import {
89 GetTransactionsCountParams ,
910 GetTransactionsParams ,
@@ -32,47 +33,72 @@ export default class TransactionQueryBuilder {
3233 private createBlockConditions (
3334 params : GetTransactionsParams ,
3435 queryParams : Array < string | number | boolean > ,
36+ maxHeightFromDb : number ,
3537 ) {
36- const { blockHash, chainId, maxHeight, minHeight } = params ;
38+ const { blockHash, chainId, maxHeight, minHeight, accountName } = params ;
3739 let blocksConditions = '' ;
3840 const blockParams : ( string | number | boolean ) [ ] = [ ...queryParams ] ;
3941
4042 blockParams . push ( true ) ;
4143 blocksConditions += `WHERE b.canonical = $${ blockParams . length } ` ;
4244
43- // Add block hash condition if specified
4445 if ( blockHash ) {
4546 blockParams . push ( blockHash ) ;
4647 const op = this . operator ( blockParams . length ) ;
4748 blocksConditions += `${ op } b.hash = $${ blockParams . length } ` ;
4849 }
4950
50- // Add maximum height condition if specified
51- if ( maxHeight ) {
51+ if ( isNullOrUndefined ( accountName ) && maxHeight && ! minHeight ) {
5252 blockParams . push ( maxHeight ) ;
5353 const op = this . operator ( blockParams . length ) ;
54- blocksConditions += `${ op } b."height" <= $${ blockParams . length } ` ;
54+ const secondCondition = `LEAST($${ blockParams . length } , ${ maxHeightFromDb } ) - 20` ;
55+ blocksConditions += `${ op } b."height" <= $${ blockParams . length } AND b."height" >= ${ secondCondition } ` ;
56+ }
57+
58+ if ( isNullOrUndefined ( accountName ) && minHeight && ! maxHeight ) {
59+ if ( minHeight < 0 ) {
60+ throw new Error ( 'minHeight cannot be less than 0' ) ;
61+ }
62+ blockParams . push ( minHeight ) ;
63+ const op = this . operator ( blockParams . length ) ;
64+ blocksConditions += `${ op } b."height" >= $${ blockParams . length } AND b."height" <= $${ blockParams . length } + 20` ;
5565 }
5666
57- // Add minimum height condition if specified
58- if ( minHeight ) {
67+ if ( isNullOrUndefined ( accountName ) && minHeight && maxHeight ) {
68+ if ( minHeight > maxHeight ) {
69+ throw new Error ( 'minHeight cannot be greater than maxHeight' ) ;
70+ }
71+
72+ blockParams . push ( minHeight ) ;
73+ const op = this . operator ( blockParams . length ) ;
74+ blockParams . push ( maxHeight ) ;
75+ const secondCondition = `LEAST($${ blockParams . length - 1 } + 20, $${ blockParams . length } )` ;
76+ blocksConditions += `${ op } b."height" >= $${ blockParams . length - 1 } AND b."height" <= ${ secondCondition } ` ;
77+ }
78+
79+ if ( ! isNullOrUndefined ( accountName ) && minHeight ) {
5980 blockParams . push ( minHeight ) ;
6081 const op = this . operator ( blockParams . length ) ;
6182 blocksConditions += `${ op } b."height" >= $${ blockParams . length } ` ;
6283 }
6384
64- // Add chain ID condition if specified
65- if ( chainId ) {
66- blockParams . push ( chainId ) ;
85+ if ( ! isNullOrUndefined ( accountName ) && maxHeight ) {
86+ blockParams . push ( maxHeight ) ;
6787 const op = this . operator ( blockParams . length ) ;
68- blocksConditions += `${ op } b."chainId" = $${ blockParams . length } ` ;
88+ blocksConditions += `${ op } b."height" < = $${ blockParams . length } ` ;
6989 }
7090
71- // Force query to retrieve a smaller set of blocks since only using chainId doesn't filter many rows
72- if ( chainId && ! params . after && ! params . before && ! minHeight && ! maxHeight ) {
91+ if ( ! isNullOrUndefined ( accountName ) && minHeight && maxHeight ) {
92+ blockParams . push ( minHeight ) ;
93+ const op = this . operator ( blockParams . length ) ;
94+ blockParams . push ( maxHeight ) ;
95+ blocksConditions += `${ op } b."height" >= $${ blockParams . length - 1 } AND b."height" <= $${ blockParams . length } ` ;
96+ }
97+
98+ if ( chainId ) {
7399 blockParams . push ( chainId ) ;
74100 const op = this . operator ( blockParams . length ) ;
75- blocksConditions += `${ op } b."chainId" = $${ blockParams . length } AND b."height" > (SELECT max(height) FROM "Blocks") - 1000 ` ;
101+ blocksConditions += `${ op } b."chainId" = $${ blockParams . length } ` ;
76102 }
77103
78104 return { blocksConditions, blockParams } ;
@@ -91,7 +117,15 @@ export default class TransactionQueryBuilder {
91117 params : GetTransactionsParams ,
92118 queryParams : Array < string | number | boolean > ,
93119 ) {
94- const { accountName, after, before, requestKey, fungibleName, hasTokenId = false } = params ;
120+ const {
121+ accountName,
122+ after,
123+ before,
124+ requestKey,
125+ fungibleName,
126+ hasTokenId = false ,
127+ isCoinbase,
128+ } = params ;
95129 let conditions = '' ;
96130
97131 const transactionParams : ( string | number ) [ ] = [ ] ;
@@ -103,6 +137,10 @@ export default class TransactionQueryBuilder {
103137 transactionParams . push ( accountName ) ;
104138 const op = localOperator ( transactionParams . length ) ;
105139 conditions += `${ op } t.sender = $${ queryParams . length + transactionParams . length } ` ;
140+ } else if ( ! isCoinbase ) {
141+ transactionParams . push ( 'coinbase' ) ;
142+ const op = localOperator ( transactionParams . length ) ;
143+ conditions += `${ op } t.sender != $${ queryParams . length + transactionParams . length } ` ;
106144 }
107145
108146 // Add 'after' cursor condition for pagination
@@ -173,10 +211,21 @@ export default class TransactionQueryBuilder {
173211 before ?: string | null ;
174212 order : string ;
175213 limit : number ;
214+ maxHeightFromDb : number ;
176215 } ,
177216 ) {
178- const { blockHash, chainId, maxHeight, minHeight, minimumDepth, limit, order, after, before } =
179- params ;
217+ const {
218+ blockHash,
219+ chainId,
220+ maxHeight,
221+ minHeight,
222+ minimumDepth,
223+ limit,
224+ order,
225+ after,
226+ before,
227+ maxHeightFromDb,
228+ } = params ;
180229
181230 // Determine if block-based filtering is the primary access pattern
182231 const isBlockQueryFirst = blockHash || minHeight || maxHeight || minimumDepth || chainId ;
@@ -189,9 +238,11 @@ export default class TransactionQueryBuilder {
189238 // Build query conditions based on the primary access pattern
190239 if ( isBlockQueryFirst ) {
191240 // Start with block conditions when block filtering is primary
192- const { blockParams, blocksConditions : bConditions } = this . createBlockConditions ( params , [
193- limit ,
194- ] ) ;
241+ const { blockParams, blocksConditions : bConditions } = this . createBlockConditions (
242+ params ,
243+ [ limit ] ,
244+ maxHeightFromDb ,
245+ ) ;
195246
196247 const { params : txParams , conditions : txConditions } = this . createTransactionConditions (
197248 { ...params , after, before } ,
@@ -210,6 +261,7 @@ export default class TransactionQueryBuilder {
210261 const { blocksConditions : bConditions , blockParams } = this . createBlockConditions (
211262 params ,
212263 txParams ,
264+ maxHeightFromDb ,
213265 ) ;
214266
215267 queryParams . push ( ...blockParams ) ;
@@ -231,27 +283,26 @@ export default class TransactionQueryBuilder {
231283 t.id AS id,
232284 t.creationtime AS "creationTime",
233285 t.hash AS "hashTransaction",
234- td.nonce AS "nonceTransaction",
235- td.sigs AS sigs,
236- td.continuation AS continuation,
286+ NULL AS "nonceTransaction",
287+ NULL AS sigs,
288+ NULL AS continuation,
237289 t.num_events AS "eventCount",
238- td.pactid AS "pactId",
239- td.proof AS proof,
240- td.rollback AS rollback,
290+ NULL AS "pactId",
291+ NULL AS proof,
292+ NULL AS rollback,
241293 t.txid AS txid,
242294 b.height AS "height",
243295 b."hash" AS "blockHash",
244296 b."chainId" AS "chainId",
245- td.gas AS "gas",
246- td.step AS step,
247- td.data AS data,
248- td.code AS code,
297+ NULL AS "gas",
298+ NULL AS step,
299+ NULL AS data,
300+ NULL AS code,
249301 t.logs AS "logs",
250302 t.result AS "result",
251303 t.requestkey AS "requestKey"
252304 FROM filtered_block b
253305 JOIN "Transactions" t ON b.id = t."blockId"
254- ${ params . isCoinbase ? 'LEFT ' : '' } JOIN "TransactionDetails" td ON t.id = td."transactionId"
255306 ${ transactionsConditions }
256307 ORDER BY t.creationtime ${ order } , t.id ${ order }
257308 LIMIT $1
@@ -269,29 +320,26 @@ export default class TransactionQueryBuilder {
269320 t.id AS id,
270321 t.creationtime AS "creationTime",
271322 t.hash AS "hashTransaction",
272- td.nonce AS "nonceTransaction",
273- td.sigs AS sigs,
274- td.continuation AS continuation,
323+ NULL AS "nonceTransaction",
324+ NULL AS sigs,
325+ NULL AS continuation,
275326 t.num_events AS "eventCount",
276- td.pactid AS "pactId",
277- td.proof AS proof,
278- td.rollback AS rollback,
327+ NULL AS "pactId",
328+ NULL AS proof,
329+ NULL AS rollback,
279330 t.txid AS txid,
280331 b.height AS "height",
281332 b."hash" AS "blockHash",
282333 b."chainId" AS "chainId",
283- td.gas AS "gas",
284- td.step AS step,
285- td.data AS data,
286- td.code AS code,
287- td.nonce,
288- td.sigs,
334+ NULL AS "gas",
335+ NULL AS step,
336+ NULL AS data,
337+ NULL AS code,
289338 t.logs AS "logs",
290339 t.result AS "result",
291340 t.requestkey AS "requestKey"
292341 FROM filtered_transactions t
293342 JOIN "Blocks" b ON b.id = t."blockId"
294- ${ params . isCoinbase ? 'LEFT ' : '' } JOIN "TransactionDetails" td ON t.id = td."transactionId"
295343 ${ blocksConditions }
296344 LIMIT $1
297345 ` ;
@@ -327,34 +375,37 @@ export default class TransactionQueryBuilder {
327375 whereCondition = ` WHERE (t.creationtime, t.id) > ($2, $3)` ;
328376 }
329377
378+ if ( ! params . isCoinbase ) {
379+ whereCondition += ` AND t.sender != 'coinbase'` ;
380+ }
381+
330382 whereCondition += ` AND b.canonical = true` ;
331383
332384 let query = `
333385 SELECT
334386 t.id AS id,
335387 t.creationtime AS "creationTime",
336388 t.hash AS "hashTransaction",
337- td.nonce AS "nonceTransaction",
338- td.sigs AS sigs,
339- td.continuation AS continuation,
389+ NULL AS "nonceTransaction",
390+ NULL AS sigs,
391+ NULL AS continuation,
340392 t.num_events AS "eventCount",
341- td.pactid AS "pactId",
342- td.proof AS proof,
343- td.rollback AS rollback,
393+ NULL AS "pactId",
394+ NULL AS proof,
395+ NULL AS rollback,
344396 t.txid AS txid,
345397 b.height AS "height",
346398 b."hash" AS "blockHash",
347399 b."chainId" AS "chainId",
348- td.gas AS "gas",
349- td.step AS step,
350- td.data AS data,
351- td.code AS code,
400+ NULL AS "gas",
401+ NULL AS step,
402+ NULL AS data,
403+ NULL AS code,
352404 t.logs AS "logs",
353405 t.result AS "result",
354406 t.requestkey AS "requestKey"
355407 FROM "Transactions" t
356408 JOIN "Blocks" b ON b.id = t."blockId"
357- ${ params . isCoinbase ? 'LEFT ' : '' } JOIN "TransactionDetails" td ON t.id = td."transactionId"
358409 ${ whereCondition }
359410 ORDER BY t.creationtime ${ params . order } , t.id ${ params . order }
360411 LIMIT $1
0 commit comments