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
SQLite migration code #10551
SQLite migration code #10551
Conversation
…ith-sqlite' into feature/2023-04-24-Sqlite-migration # Conflicts: # WalletWasabi/Stores/IndexStore.cs
…ith-sqlite' into feature/2023-04-24-Sqlite-migration
Sorry @kiminuo I misunderstood something in yesterday's meetings. I thought it takes 10 minutes to migrate but I see it is less than 1 minute. That is acceptable UX. Where will the user wait for the migration? |
Do not go down that road, it is long and complicated and not worth it for just only 1 minute (or less). It is enough if wallet loading will take longer. |
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.
tACK 2395e63
On the first run:
INFO IndexStore.MigrateToSqliteNoLock (124) Filters to add is 1601354. Elapsed seconds 6.
INFO IndexStore.MigrateToSqliteNoLock (127) Migration to SQLite was finished in 13 seconds.
INFO IndexStore.Dispose (77) InitializeAsync finished in 13.12 seconds.
It happens on the initial page which is frozen at the moment. You can actually try it. I feel like the UX is not great at the moment but maybe it's acceptable given it's one time thing. Maybe we should just mention it in the next release notes so that people are not suprised. Using https://www.meziantou.net/split-a-string-into-lines-without-allocation.htm would shorten the time required for the operation by about half, I suspect, because we allocate many and many strings by reading the At the moment, I don't have another good idea how to make it faster without non-trivial time investment. Maybe someone else has an idea how to make it faster? |
@MaxHillebrand It should be slightly faster now. |
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.
TACK c586c42
30 seconds now.
I see the log before the UI opens, so loading time is seriously not an issue.
WalletWasabi/Stores/BitcoinStore.cs
Outdated
@@ -44,6 +44,9 @@ public class BitcoinStore | |||
|
|||
public async Task InitializeAsync(CancellationToken cancel = default) | |||
{ | |||
// Switch to a different thread so that we can confinue with other initialization tasks and UI can show up. | |||
await Task.Yield(); |
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.
Not entirely necessary but without it, I can see white screen instead of the initial Avalonia page.
{ | ||
Header = header; | ||
_filter = filter; | ||
FilterData = filterData; | ||
_filter = new(() => new GolombRiceFilter(filterData, 20, 1 << 20), LazyThreadSafetyMode.ExecutionAndPublication); |
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.
Accessing filter bytes through GolombRiceFilter
is slow. It's better to touch GolombRiceFilter
only when really necessary.
if (i % 100_000 == 0) | ||
{ | ||
IndexStorage.BulkAppend(filters); | ||
filters.Clear(); | ||
} |
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.
It seems it's slightly faster when "chunked". Not by much.
The period of the migration is OK. Regarding the UX - can this migration take place exactly the same way as it was before with processing the filters? There was no UI freeze when the filters were not ready. |
TestNet ⚡
MainNet
My only nitpick is that the UI is totally frozen while the migration is happening. |
Make sure when testing this, that wallet from the latest release will be loaded as fast as with this PR. There should not be a noticeable change. |
I have attempted to modify the implementation to avoid the frozen UI issue. However, now it's a bit more involved and a bit more risky. So it requires more careful review. It's also a bit hackish. The idea is that when we get first filters batch, then we just run migration and fix If anyone has a better idea how to approach this, I'm all ears. |
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.
NACK for the current solution as you said is a hack - from the worst kind. I am sure you can find it better, please elaborate more.
I'm not sure what constitutes the worst kind of hack. What are the properties you don't like? Thinking about it a bit more, I believe we can put the code here
SmartHeaderChain is used on many and many places. So I believe the original approach was actually better (maybe try to make it even faster so that it does not mind too much that GUI is not responsive?).
|
The |
…Sqlite-migration # Conflicts: # WalletWasabi/Stores/IndexStore.cs
This reverts commit d1fa430. # Conflicts: # WalletWasabi/Stores/IndexStore.cs
I reverted to my original approach and added your X second delay trick (I'm not entirely sure why it works though). |
What's needed to push this over the finish line? |
David's ACK/NACK on the approach. Review&testing by others will help too. |
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.
tested it works perfectly. One concern to address.
WalletWasabi/Stores/IndexStore.cs
Outdated
int i = 0; | ||
|
||
// Helps to avoid UI freezing. | ||
await Task.Delay(5_000, cancellationToken).ConfigureAwait(false); |
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.
This help only because it is giving back the execution to the caller thread. When it returns here it might be running on a separate thread after (.ConfigureAwait(false)
) , might not - it is not guaranteed. If ThreadPoll will assign the task to the UI thread (random) it will still freeze the UI.
Because you are not having an async method for MigrateToSqliteNoLockAsync
(perf reasons cACK) I suggest removing the Delay and changing it back to the sync method.
Then call it with
await Task.Run(MigrateToSqliteNoLockAsync);
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.
There is already using (await IndexLock.LockAsync(cancellationToken).ConfigureAwait(false))
, so I added:
await Task.Run(MigrateToSqliteNoLock, cancellationToken).ConfigureAwait(false);
Or is there any reason why it should be done differently?
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.
FWIW (maybe edge case, maybe useful):
My client was busy doing full rescan/filter download.
I stopped the process halfway, then checked out and ran this PR.
The log immediately says it downloaded the latest block filter (so no more filter download), however, the wallet load screen is still counting down where it left off: many hours remaining. While in logs nothing is changing.
This is expected, see second part of #10589 (comment) |
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.
tACK. 🥇
The next step is to delete the old files. Two weeks from now that PR can be merged. 17th of May. Added to the calendar. |
Follow-up to #10272
The important commit is 85f1e4a.
fixes #10589
Takes
MatureIndex.dat
and converts it toIndexStore.sqlite
.Unfortunately, the process is not very fast. It takes 43 seconds on my machine for testnet. So this PR would benefit from giving a user a visual notification that the migration is in progress. WDYT?We agreed that we should not add any UX.Note: This PR does not remove the original
MatureIndex.dat
as agreed in a previous meeting. That is a next logical step to avoid issues for developers.Testing
Remove
C:\Users\<USER>\AppData\Roaming\WalletWasabi\Client\BitcoinStore\<NETWORK>\IndexStore\IndexStore.sqlite
andIndexStore.sqlite
should be created during app's launch.Measurements
On my machine: