Skip to content

Commit f115253

Browse files
authored
Merge pull request #441 from EdgeApp/sam/dropped-tx-thrashing
Add retry delay to fix dropped transaction thrashing
2 parents 0fcd7e7 + 6cc3bf1 commit f115253

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- fixed: Added retry delay to fix dropped transaction thrashing.
6+
57
## 3.8.6 (2025-10-13)
68

79
- fixed: (QTUM) Explorer URLs

src/common/utxobased/engine/UtxoEngineProcessor.ts

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ export function makeUtxoEngineProcessor(
115115
transactionUpdateCache: {}
116116
}
117117

118+
// Track pending timeouts so they can be cleared on stop
119+
const pendingTimeouts: Set<NodeJS.Timeout> = new Set()
120+
121+
// Clear all pending timeouts
122+
const clearPendingTimeouts = (): void => {
123+
for (const timeoutId of pendingTimeouts) {
124+
clearTimeout(timeoutId)
125+
}
126+
pendingTimeouts.clear()
127+
}
128+
118129
const clearTaskCache = (): void => {
119130
for (const key of Object.keys(taskCache.addressForTransactionsCache)) {
120131
removeItem(taskCache.addressForTransactionsCache, key)
@@ -212,6 +223,7 @@ export function makeUtxoEngineProcessor(
212223
dataLayer,
213224
emitter,
214225
taskCache,
226+
pendingTimeouts,
215227
updateProgressRatio,
216228
updateSeenTxCheckpoint,
217229
io,
@@ -358,6 +370,7 @@ export function makeUtxoEngineProcessor(
358370
async stop(): Promise<void> {
359371
serverStates.stop()
360372
clearTaskCache()
373+
clearPendingTimeouts()
361374
running = false
362375
},
363376

@@ -628,6 +641,7 @@ interface CommonParams {
628641
dataLayer: DataLayer
629642
emitter: EngineEmitter
630643
taskCache: TaskCache
644+
pendingTimeouts: Set<NodeJS.Timeout>
631645
updateProgressRatio: () => void
632646
updateSeenTxCheckpoint: () => void
633647
io: EdgeIo
@@ -1154,9 +1168,18 @@ async function* processCheckTransactionConfirmation(
11541168
} catch (err) {
11551169
console.error(err)
11561170
common.log('error while processing transaction update:', err)
1157-
common.taskCache.transactionUpdateCache[txId] = {
1158-
processing: false
1159-
}
1171+
// Delay putting the transaction back into the cache to avoid thrashing
1172+
// on dropped transactions. 10 seconds is a reasonable compromise between
1173+
// thrashing and not waiting too long.
1174+
addPendingTimeout(
1175+
common,
1176+
() => {
1177+
common.taskCache.transactionUpdateCache[txId] = {
1178+
processing: false
1179+
}
1180+
},
1181+
10000
1182+
)
11601183
return false
11611184
}
11621185
}
@@ -1681,3 +1704,22 @@ const addToDataLayerUtxoCache = (
16811704
dataLayerUtxoCache[scriptPubkey] = dataLayerUtxos
16821705
dataLayerUtxos.full = dataLayerUtxos.utxos.length >= requiredCount
16831706
}
1707+
1708+
/**
1709+
* This adds a pending timeout to the common.pendingTimeouts set.
1710+
* It will call the callback after the timeout.
1711+
*
1712+
* This utility is a safe way to add pending timeouts for the processor because
1713+
* it will clear the timeout when the processor stops.
1714+
*/
1715+
const addPendingTimeout = (
1716+
common: CommonParams,
1717+
callback: () => void,
1718+
timeout: number
1719+
): void => {
1720+
const timeoutId = setTimeout(() => {
1721+
common.pendingTimeouts.delete(timeoutId)
1722+
callback()
1723+
}, timeout)
1724+
common.pendingTimeouts.add(timeoutId)
1725+
}

0 commit comments

Comments
 (0)