-
Notifications
You must be signed in to change notification settings - Fork 16
Reduce UI lag: dedup and throttle UTXO engine emissions #446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
b7f32d5
1b7cf46
e0ca938
6a886a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -157,7 +157,7 @@ export function makeUtxoEngineProcessor( | |
| **/ | ||
| const processesPerAddress = 2 | ||
| let processedCount = 0 | ||
| let processedPercent = 0 // last sync ratio emitted | ||
| let processedPercent = 0 // in-memory high-water-mark; resets to 0 on engine creation | ||
| const updateProgressRatio = async (): Promise<void> => { | ||
| // Avoid re-sending sync ratios / sending ratios larger than 1 | ||
| if (processedPercent >= 1) return | ||
|
|
@@ -174,13 +174,19 @@ export function makeUtxoEngineProcessor( | |
| if (expectedProcessCount === 0) throw new Error('No addresses to process') | ||
|
|
||
| const percent = processedCount / expectedProcessCount | ||
|
|
||
| // High-water-mark: never report progress going backwards. This can happen | ||
| // when setLookAhead discovers new addresses and inflates expectedProcessCount, | ||
| // or when start() is called again (pause/unpause) and processedCount resets. | ||
| if (percent <= processedPercent) return | ||
|
|
||
| if (percent - processedPercent > CACHE_THROTTLE || percent === 1) { | ||
| log( | ||
| `processed changed, percent: ${percent}, processedCount: ${processedCount}, totalCount: ${expectedProcessCount}` | ||
| ) | ||
| processedPercent = percent | ||
| common.updateSeenTxCheckpoint() | ||
| emitter.emit(EngineEvent.ADDRESSES_CHECKED, percent) | ||
| emitter.emitAddressesChecked(percent) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -360,8 +366,11 @@ export function makeUtxoEngineProcessor( | |
| return { | ||
| processedPercent, | ||
| async start(): Promise<void> { | ||
| // Reset the count so the address walk restarts, but keep processedPercent | ||
| // as an in-memory high-water-mark. This prevents the reported ratio from | ||
| // rolling backwards if start() is called again (pause/unpause) or if | ||
| // setLookAhead discovers new addresses and inflates the denominator. | ||
| processedCount = 0 | ||
| processedPercent = 0 | ||
|
|
||
| await run() | ||
| serverStates.refillServers() | ||
|
|
@@ -1261,9 +1270,12 @@ async function* processAddressForTransactions( | |
| // The tx unconfirmed or confirmed after/at the last seenTxCheckpoint | ||
| (tx.blockHeight === 0 || tx.blockHeight > seenTxBlockHeight) | ||
|
|
||
| common.emitter.emit(EngineEvent.TRANSACTIONS, [ | ||
| { isNew, transaction: edgeTx } | ||
| ]) | ||
| // Only emit if tx is new or changed (blockHeight changed) | ||
| if (existingTx == null || existingTx.blockHeight !== tx.blockHeight) { | ||
| common.emitter.emit(EngineEvent.TRANSACTIONS, [ | ||
| { isNew, transaction: edgeTx } | ||
| ]) | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Transaction emission skipped when ourAmount changes but blockHeight unchangedMedium Severity The new dedup guard only emits when |
||
|
|
||
| if (edgeTx.blockHeight > common.maxSeenTxBlockHeight) { | ||
| common.maxSeenTxBlockHeight = edgeTx.blockHeight | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throttled progress ratios pollute dedup cache prematurely
Low Severity
emitAddressesCheckedsetslastAddressesCheckedRatiobefore the global 500ms throttle check. When the throttle suppresses an emission, the dedup cache records a value that was never actually delivered to listeners. This makes the "last-value tracking" semantically incorrect — it tracks the last input rather than the last emitted value. In the current single-call-site usage with monotonically increasing ratios, this has no observable effect, but it introduces a latent correctness issue if the method is ever reused elsewhere.