@@ -1701,6 +1701,10 @@ export class PgDataStore
1701
1701
microblocks : string [ ] ;
1702
1702
}
1703
1703
) : Promise < { updatedTxs : DbTx [ ] } > {
1704
+ const bufIndexBlockHash = hexToBuffer ( args . indexBlockHash ) ;
1705
+ const bufBlockHash = hexToBuffer ( args . blockHash ) ;
1706
+ const bufMicroblockHashes = args . microblocks . map ( mb => hexToBuffer ( mb ) ) ;
1707
+
1704
1708
// Flag orphaned microblock rows as `microblock_canonical=false`
1705
1709
const updatedMicroblocksQuery = await client . query (
1706
1710
`
@@ -1711,9 +1715,9 @@ export class PgDataStore
1711
1715
[
1712
1716
args . isMicroCanonical ,
1713
1717
args . isCanonical ,
1714
- hexToBuffer ( args . indexBlockHash ) ,
1715
- hexToBuffer ( args . blockHash ) ,
1716
- args . microblocks . map ( mb => hexToBuffer ( mb ) ) ,
1718
+ bufIndexBlockHash ,
1719
+ bufBlockHash ,
1720
+ bufMicroblockHashes ,
1717
1721
]
1718
1722
) ;
1719
1723
if ( updatedMicroblocksQuery . rowCount !== args . microblocks . length ) {
@@ -1734,10 +1738,10 @@ export class PgDataStore
1734
1738
[
1735
1739
args . isMicroCanonical ,
1736
1740
args . isCanonical ,
1737
- hexToBuffer ( args . indexBlockHash ) ,
1738
- hexToBuffer ( args . blockHash ) ,
1741
+ bufIndexBlockHash ,
1742
+ bufBlockHash ,
1739
1743
args . burnBlockTime ,
1740
- args . microblocks . map ( mb => hexToBuffer ( mb ) ) ,
1744
+ bufMicroblockHashes ,
1741
1745
]
1742
1746
) ;
1743
1747
// Any txs restored need to be pruned from the mempool
@@ -1757,8 +1761,8 @@ export class PgDataStore
1757
1761
const updatedAssociatedTableParams = [
1758
1762
args . isMicroCanonical ,
1759
1763
args . isCanonical ,
1760
- hexToBuffer ( args . indexBlockHash ) ,
1761
- args . microblocks . map ( mb => hexToBuffer ( mb ) ) ,
1764
+ bufIndexBlockHash ,
1765
+ bufMicroblockHashes ,
1762
1766
updatedMbTxs . map ( tx => hexToBuffer ( tx . tx_id ) ) ,
1763
1767
] ;
1764
1768
for ( const associatedTableName of TX_METADATA_TABLES ) {
@@ -1774,16 +1778,14 @@ export class PgDataStore
1774
1778
) ;
1775
1779
}
1776
1780
1777
- // TODO: [bug] This is can end up with incorrect canonical state due to missing the `index_block_hash` column
1778
- // which is required for the way micro-reorgs are handled. Queries against this table can work around the
1779
- // bug by using the `txs` table canonical state in the JOIN condition.
1780
-
1781
1781
// Update `principal_stx_txs`
1782
1782
await client . query (
1783
1783
`UPDATE principal_stx_txs
1784
- SET canonical = $1, microblock_canonical = $2
1785
- WHERE tx_id = ANY ($3)` ,
1786
- [ args . isCanonical , args . isMicroCanonical , updatedMbTxs . map ( tx => hexToBuffer ( tx . tx_id ) ) ]
1784
+ SET microblock_canonical = $1, canonical = $2, index_block_hash = $3
1785
+ WHERE microblock_hash = ANY($4)
1786
+ AND (index_block_hash = $3 OR index_block_hash = '\\x'::bytea)
1787
+ AND tx_id = ANY($5)` ,
1788
+ updatedAssociatedTableParams
1787
1789
) ;
1788
1790
1789
1791
return { updatedTxs : updatedMbTxs } ;
@@ -2327,9 +2329,9 @@ export class PgDataStore
2327
2329
// Update `principal_stx_txs`
2328
2330
await client . query (
2329
2331
`UPDATE principal_stx_txs
2330
- SET canonical = $1
2331
- WHERE tx_id = ANY ($2) ` ,
2332
- [ canonical , txIds . map ( tx => hexToBuffer ( tx . tx_id ) ) ]
2332
+ SET canonical = $2
2333
+ WHERE tx_id = ANY($3) AND index_block_hash = $1 AND canonical != $2 ` ,
2334
+ [ indexBlockHash , canonical , txIds . map ( tx => hexToBuffer ( tx . tx_id ) ) ]
2333
2335
) ;
2334
2336
2335
2337
const minerRewardResults = await client . query (
@@ -4537,8 +4539,8 @@ export class PgDataStore
4537
4539
}
4538
4540
eventsQueries . push ( `
4539
4541
SELECT
4540
- tx_id, event_index, tx_index, block_height, locked_address as sender, NULL as recipient,
4541
- locked_amount as amount, unlock_height, NULL as asset_identifier, NULL as contract_identifier,
4542
+ tx_id, event_index, tx_index, block_height, locked_address as sender, NULL as recipient,
4543
+ locked_amount as amount, unlock_height, NULL as asset_identifier, NULL as contract_identifier,
4542
4544
'0'::bytea as value, NULL as topic,
4543
4545
${ DbEventTypeId . StxLock } as event_type_id, 0 as asset_event_type_id
4544
4546
FROM stx_lock_events
@@ -4550,8 +4552,8 @@ export class PgDataStore
4550
4552
}
4551
4553
eventsQueries . push ( `
4552
4554
SELECT
4553
- tx_id, event_index, tx_index, block_height, sender, recipient,
4554
- amount, 0 as unlock_height, NULL as asset_identifier, NULL as contract_identifier,
4555
+ tx_id, event_index, tx_index, block_height, sender, recipient,
4556
+ amount, 0 as unlock_height, NULL as asset_identifier, NULL as contract_identifier,
4555
4557
'0'::bytea as value, NULL as topic,
4556
4558
${ DbEventTypeId . StxAsset } as event_type_id, asset_event_type_id
4557
4559
FROM stx_events
@@ -4563,8 +4565,8 @@ export class PgDataStore
4563
4565
}
4564
4566
eventsQueries . push ( `
4565
4567
SELECT
4566
- tx_id, event_index, tx_index, block_height, sender, recipient,
4567
- amount, 0 as unlock_height, asset_identifier, NULL as contract_identifier,
4568
+ tx_id, event_index, tx_index, block_height, sender, recipient,
4569
+ amount, 0 as unlock_height, asset_identifier, NULL as contract_identifier,
4568
4570
'0'::bytea as value, NULL as topic,
4569
4571
${ DbEventTypeId . FungibleTokenAsset } as event_type_id, asset_event_type_id
4570
4572
FROM ft_events
@@ -4576,8 +4578,8 @@ export class PgDataStore
4576
4578
}
4577
4579
eventsQueries . push ( `
4578
4580
SELECT
4579
- tx_id, event_index, tx_index, block_height, sender, recipient,
4580
- 0 as amount, 0 as unlock_height, asset_identifier, NULL as contract_identifier,
4581
+ tx_id, event_index, tx_index, block_height, sender, recipient,
4582
+ 0 as amount, 0 as unlock_height, asset_identifier, NULL as contract_identifier,
4581
4583
value, NULL as topic,
4582
4584
${ DbEventTypeId . NonFungibleTokenAsset } as event_type_id, asset_event_type_id
4583
4585
FROM nft_events
@@ -4589,8 +4591,8 @@ export class PgDataStore
4589
4591
}
4590
4592
eventsQueries . push ( `
4591
4593
SELECT
4592
- tx_id, event_index, tx_index, block_height, NULL as sender, NULL as recipient,
4593
- 0 as amount, 0 as unlock_height, NULL as asset_identifier, contract_identifier,
4594
+ tx_id, event_index, tx_index, block_height, NULL as sender, NULL as recipient,
4595
+ 0 as amount, 0 as unlock_height, NULL as asset_identifier, contract_identifier,
4594
4596
value, topic,
4595
4597
${ DbEventTypeId . SmartContractLog } as event_type_id, 0 as asset_event_type_id
4596
4598
FROM contract_logs
@@ -4605,7 +4607,7 @@ export class PgDataStore
4605
4607
`WITH events AS ( ` +
4606
4608
eventsQueries . join ( `\nUNION\n` ) +
4607
4609
`)
4608
- SELECT *
4610
+ SELECT *
4609
4611
FROM events JOIN txs USING(tx_id)
4610
4612
WHERE txs.canonical = true AND txs.microblock_canonical = true
4611
4613
ORDER BY events.block_height DESC, microblock_sequence DESC, events.tx_index DESC, event_index DESC
@@ -4738,9 +4740,11 @@ export class PgDataStore
4738
4740
*/
4739
4741
async updatePrincipalStxTxs ( client : ClientBase , tx : DbTx , events : DbStxEvent [ ] ) {
4740
4742
const txIdBuffer = hexToBuffer ( tx . tx_id ) ;
4743
+ const indexBlockHashBuffer = hexToBuffer ( tx . index_block_hash ) ;
4744
+ const microblockHashBuffer = hexToBuffer ( tx . microblock_hash ) ;
4741
4745
const insertPrincipalStxTxs = async ( principals : string [ ] ) => {
4742
4746
principals = [ ...new Set ( principals ) ] ; // Remove duplicates
4743
- const columnCount = 7 ;
4747
+ const columnCount = 9 ;
4744
4748
const insertParams = this . generateParameterizedInsertString ( {
4745
4749
rowCount : principals . length ,
4746
4750
columnCount,
@@ -4751,31 +4755,21 @@ export class PgDataStore
4751
4755
principal ,
4752
4756
txIdBuffer ,
4753
4757
tx . block_height ,
4758
+ indexBlockHashBuffer ,
4759
+ microblockHashBuffer ,
4754
4760
tx . microblock_sequence ,
4755
4761
tx . tx_index ,
4756
4762
tx . canonical ,
4757
4763
tx . microblock_canonical
4758
4764
) ;
4759
4765
}
4760
- // If there was already an existing (`tx_id`, `principal`) pair in the table, we will update
4761
- // the entry's data to reflect the newer transaction state.
4762
4766
const insertQuery = `
4763
4767
INSERT INTO principal_stx_txs
4764
- (principal, tx_id, block_height, microblock_sequence, tx_index, canonical, microblock_canonical)
4768
+ (principal, tx_id,
4769
+ block_height, index_block_hash, microblock_hash, microblock_sequence, tx_index,
4770
+ canonical, microblock_canonical)
4765
4771
VALUES ${ insertParams }
4766
- ON CONFLICT ON CONSTRAINT unique_principal_tx_id
4767
- DO UPDATE
4768
- SET block_height = EXCLUDED.block_height,
4769
- microblock_sequence = EXCLUDED.microblock_sequence,
4770
- tx_index = EXCLUDED.tx_index,
4771
- canonical = EXCLUDED.canonical,
4772
- microblock_canonical = EXCLUDED.microblock_canonical
4773
- WHERE EXCLUDED.block_height > principal_stx_txs.block_height
4774
- OR EXCLUDED.microblock_sequence > principal_stx_txs.microblock_sequence
4775
- OR EXCLUDED.tx_index > principal_stx_txs.tx_index
4776
- OR EXCLUDED.canonical != principal_stx_txs.canonical
4777
- OR EXCLUDED.microblock_canonical != principal_stx_txs.microblock_canonical
4778
- ` ;
4772
+ ON CONFLICT ON CONSTRAINT unique_principal_tx_id_index_block_hash_microblock_hash DO NOTHING` ;
4779
4773
const insertQueryName = `insert-batch-principal_stx_txs_${ columnCount } x${ principals . length } ` ;
4780
4774
const insertQueryConfig : QueryConfig = {
4781
4775
name : insertQueryName ,
@@ -5868,21 +5862,17 @@ export class PgDataStore
5868
5862
// join against `txs` to get the full transaction objects only for that page.
5869
5863
`
5870
5864
WITH stx_txs AS (
5871
- SELECT tx_id, ${ countOverColumn ( ) }
5865
+ SELECT tx_id, index_block_hash, microblock_hash, ${ countOverColumn ( ) }
5872
5866
FROM principal_stx_txs
5873
5867
WHERE principal = $1 AND ${ blockCond }
5868
+ AND canonical = TRUE AND microblock_canonical = TRUE
5874
5869
ORDER BY block_height DESC, microblock_sequence DESC, tx_index DESC
5875
5870
LIMIT $2
5876
5871
OFFSET $3
5877
5872
)
5878
5873
SELECT ${ txColumns ( ) } , ${ abiColumn ( ) } , count
5879
5874
FROM stx_txs
5880
- INNER JOIN txs
5881
- ON (stx_txs.tx_id = txs.tx_id
5882
- AND txs.canonical = TRUE
5883
- AND txs.microblock_canonical = TRUE)
5884
- ORDER BY txs.block_height DESC, txs.microblock_sequence DESC, txs.tx_index DESC
5885
- LIMIT $2
5875
+ INNER JOIN txs USING (tx_id, index_block_hash, microblock_hash)
5886
5876
` ,
5887
5877
[ args . stxAddress , args . limit , args . offset , args . blockHeight ]
5888
5878
) ;
0 commit comments