@@ -2178,63 +2178,99 @@ export class PgWriteStore extends PgStore {
2178
2178
txIds : string [ ] ,
2179
2179
mempool : boolean = true
2180
2180
) : Promise < void > {
2181
- for ( const txId of txIds ) {
2182
- // If a transaction with equal nonce was confirmed in a block, mark all conflicting mempool
2183
- // txs as RBF. Otherwise, look for the one with the highest fee in the mempool and RBF all the
2184
- // others.
2185
- //
2186
- // Note that we're not filtering by `pruned` when we look at the mempool, because we want the
2187
- // RBF data to be retroactively applied to all conflicting txs we've ever seen.
2181
+ if ( txIds . length === 0 ) return ;
2182
+
2183
+ // If a transaction with equal nonce was confirmed in a block, mark all conflicting mempool txs
2184
+ // as RBF. Otherwise, look for the one with the highest fee in the mempool and RBF all the
2185
+ // others.
2186
+ //
2187
+ // Note that we're not filtering by `pruned` when we look at the mempool, because we want the
2188
+ // RBF data to be retroactively applied to all conflicting txs we've ever seen.
2189
+ for ( const batch of batchIterate ( txIds , INSERT_BATCH_SIZE ) ) {
2188
2190
await sql `
2189
- WITH source_tx AS (
2190
- SELECT
2191
+ WITH input_txids (tx_id) AS (
2192
+ VALUES ${ sql ( batch . map ( id => [ id . replace ( '0x' , '\\x' ) ] ) ) }
2193
+ ),
2194
+ source_txs AS (
2195
+ SELECT DISTINCT
2196
+ tx_id,
2191
2197
(CASE sponsored WHEN true THEN sponsor_address ELSE sender_address END) AS address,
2192
- nonce, fee_rate
2198
+ nonce
2193
2199
FROM ${ mempool ? sql `mempool_txs` : sql `txs` }
2194
- WHERE tx_id = ${ txId }
2195
- LIMIT 1
2200
+ WHERE tx_id IN (SELECT tx_id::bytea FROM input_txids)
2201
+ ),
2202
+ affected_groups AS (
2203
+ SELECT DISTINCT address, nonce
2204
+ FROM source_txs
2196
2205
),
2197
2206
same_nonce_mempool_txs AS (
2198
- SELECT tx_id, fee_rate, receipt_time
2199
- FROM mempool_txs
2200
- WHERE (sponsor_address = (SELECT address FROM source_tx) OR sender_address = (SELECT address FROM source_tx))
2201
- AND nonce = (SELECT nonce FROM source_tx)
2207
+ SELECT
2208
+ m.tx_id,
2209
+ m.fee_rate,
2210
+ m.receipt_time,
2211
+ m.pruned,
2212
+ g.address,
2213
+ g.nonce
2214
+ FROM mempool_txs m
2215
+ INNER JOIN affected_groups g
2216
+ ON m.nonce = g.nonce
2217
+ AND (m.sponsor_address = g.address OR m.sender_address = g.address)
2202
2218
),
2203
- mined_tx AS (
2204
- SELECT tx_id
2205
- FROM txs
2206
- WHERE (sponsor_address = (SELECT address FROM source_tx) OR sender_address = (SELECT address FROM source_tx))
2207
- AND nonce = (SELECT nonce FROM source_tx)
2208
- AND canonical = true
2209
- AND microblock_canonical = true
2210
- ORDER BY block_height DESC, microblock_sequence DESC, tx_index DESC
2211
- LIMIT 1
2219
+ mined_txs AS (
2220
+ SELECT
2221
+ t.tx_id,
2222
+ g.address,
2223
+ g.nonce
2224
+ FROM txs t
2225
+ INNER JOIN affected_groups g
2226
+ ON t.nonce = g.nonce
2227
+ AND (t.sponsor_address = g.address OR t.sender_address = g.address)
2228
+ WHERE t.canonical = true AND t.microblock_canonical = true
2229
+ ORDER BY t.block_height DESC, t.microblock_sequence DESC, t.tx_index DESC
2230
+ ),
2231
+ latest_mined_txs AS (
2232
+ SELECT DISTINCT ON (address, nonce) tx_id, address, nonce
2233
+ FROM mined_txs
2212
2234
),
2213
- highest_fee_mempool_tx AS (
2214
- SELECT tx_id
2235
+ highest_fee_mempool_txs AS (
2236
+ SELECT DISTINCT ON (address, nonce) tx_id, address, nonce
2215
2237
FROM same_nonce_mempool_txs
2216
- ORDER BY fee_rate DESC, receipt_time DESC
2217
- LIMIT 1
2238
+ ORDER BY address, nonce, fee_rate DESC, receipt_time DESC
2218
2239
),
2219
- winning_tx AS (
2220
- SELECT COALESCE((SELECT tx_id FROM mined_tx), (SELECT tx_id FROM highest_fee_mempool_tx)) AS tx_id
2240
+ winning_txs AS (
2241
+ SELECT
2242
+ g.address,
2243
+ g.nonce,
2244
+ COALESCE(l.tx_id, h.tx_id) AS tx_id
2245
+ FROM affected_groups g
2246
+ LEFT JOIN latest_mined_txs l USING (address, nonce)
2247
+ LEFT JOIN highest_fee_mempool_txs h USING (address, nonce)
2221
2248
),
2222
2249
txs_to_prune AS (
2223
- SELECT tx_id, pruned
2224
- FROM mempool_txs
2225
- WHERE tx_id IN (SELECT tx_id FROM same_nonce_mempool_txs)
2226
- AND tx_id <> (SELECT tx_id FROM winning_tx)
2250
+ SELECT
2251
+ s.tx_id,
2252
+ s.pruned
2253
+ FROM same_nonce_mempool_txs s
2254
+ INNER JOIN winning_txs w USING (address, nonce)
2255
+ WHERE s.tx_id <> w.tx_id
2227
2256
),
2228
- mempool_count_updates AS (
2229
- UPDATE chain_tip SET
2230
- mempool_tx_count = mempool_tx_count - (SELECT COUNT(*) FROM txs_to_prune WHERE pruned = false),
2231
- mempool_updated_at = NOW()
2257
+ pruned AS (
2258
+ UPDATE mempool_txs m
2259
+ SET pruned = TRUE,
2260
+ status = ${ DbTxStatus . DroppedReplaceByFee } ,
2261
+ replaced_by_tx_id = (
2262
+ SELECT w.tx_id
2263
+ FROM winning_txs w
2264
+ INNER JOIN same_nonce_mempool_txs s ON w.address = s.address AND w.nonce = s.nonce
2265
+ WHERE s.tx_id = m.tx_id
2266
+ )
2267
+ FROM txs_to_prune p
2268
+ WHERE m.tx_id = p.tx_id
2269
+ RETURNING m.tx_id
2232
2270
)
2233
- UPDATE mempool_txs
2234
- SET pruned = TRUE,
2235
- status = ${ DbTxStatus . DroppedReplaceByFee } ,
2236
- replaced_by_tx_id = (SELECT tx_id FROM winning_tx)
2237
- WHERE tx_id IN (SELECT tx_id FROM txs_to_prune)
2271
+ UPDATE chain_tip SET
2272
+ mempool_tx_count = mempool_tx_count - (SELECT COUNT(*) FROM txs_to_prune WHERE pruned = FALSE),
2273
+ mempool_updated_at = NOW()
2238
2274
` ;
2239
2275
}
2240
2276
}
0 commit comments