-
Notifications
You must be signed in to change notification settings - Fork 307
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
[DRAFT] added sqlx, removed rusqlite #1552
[DRAFT] added sqlx, removed rusqlite #1552
Conversation
Given that SQLx is very explicit about not supporting any kind of MSRV, I don't think switching to it would be a real option? I think the operations for |
// // migrate_schema(db_tx, Self::SCHEMA_NAME, &[schema_v0]) | ||
// Ok(()) | ||
// let db = db_tx.acquire().await.unwrap(); | ||
migrate!("./tx_graph_migrations").run(db_tx).await |
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.
I think you forgot to include these files in the PR.
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 should no longer be a problem
@matthiasdebernardini thank you for this PR. I think I figured out the problem. The trait definition was not strict enough with lifetime bounds. Please see here: https://github.com/matthiasdebernardini/bdk/pull/2 I'm wondering if #1547 will be in the beta. If so, maybe it's best I do the fix there. Edit: The fix is included in 8498a5f. |
Looking at @tnull's comment, @matthiasdebernardini can you please elaborate on what you specifically need. Is it postgres support, async support, or do you specifically need postgres + async? It'll be easier to assist if we know what the goals are. |
@evanlinjin we want to store our users wallets and load them quickly so the wallet feels snappy, that is our high level goal. We picked postgres because we like it and trust it. We are very paranoid about losing our customers wallet descriptors. Initially, I was storing the flat files in their own column, reading/writing it from the disk and uploading/downloading it from postgres (I had it working in S3 at one point as well). The reason I want to store it remotely is that we want to keep our bdk api webserver stateless, so the sqlite/flat file method wont be a good fit for us. As far async support is concerned, I am already running all our bdk code within an axum webserver, so using it is advantageous for scenarios where we need to fetch a lot of wallets all at once. We could go with a sequential (non-async/normal) method of persisting but async would be our preference. In short, we don't need either, but async postgres is our #1 preference by a long shot. I agree with @tnull our needs are very basic. I picked SQLx because I prefer SQL over an ORM and I was having a lot of success using it to finish our app. I do think if you want to offer async remote persistence for your users out-of-the-box now, then a different crate may be better. |
@matthiasdebernardini if we do the sqlx persistence in a separate crate, would we still run into the bug you mentioned in the PR description? |
It should work as long as you don't enable the rusqlite feature in that project, yes. |
I think reworking the lifetimes might help, I am still unable to make it compile.
|
340808e docs(wallet): fixes/improvements for `persisted` and `params` types (志宇) 9600293 feat(wallet)!: add persister (`P`) type param to `PersistedWallet<P>` (志宇) 0616057 revert(chain)!: rm `persit` module (志宇) a9c5f76 feat(wallet)!: remove dependency on `bdk_chain::Staged` (志宇) 06a9d6c feat(chain,wallet)!: publicize `.init_sqlite_tables` changeset methods (志宇) 039622f feat(wallet)!: introduce `WalletPersister` (志宇) Pull request description: ### Description Removed the persistence module in `bdk_chain` (which contained the `PersistWith` and `PersistAsyncWith` traits and a `Persisted<T>` wrapper). Replaced it with simplified versions that are `Wallet`-specific. The new traits (`WalletPersister` and `AsyncWalletPersister`) are simpler since they have less type-parameters (being wallet-specific). The old versions were more complex as they were intended to be used with any type. However, we need more time to finalize a works-for-all-bdk-types persistence API. Additionally, `WalletPersister` and `AsyncWalletPersister` also introduce the `initialize` method. It is handy to contain db-initialization (i.e. create tables for SQL) here. We can call `initialize` in `PersistedWallet` constructors. So the `PersistedWallet::persist` method does not need to ensure the database is initialized. To accommodate this, I made the `.init_sqlite_table` methods on changeset-types public, and removed the call of this in `from_sqlite` and `.persist_to_sqlite`. The `initialize` method now loads from the persister, so the `load` associated function is removed. There was a bug in the old `PersistAsyncWith` trait where the lifetime bounds were not strict enough (refer to the conversation in #1552). This is now fixed in the new `AsyncWalletPersister` trait. Docs for the new types are clearer (hopefully). I mentioned implementation details about the new traits and what safety checks were guaranteed in `PersistedWallet`. I think it makes sense just to have a wallet-specific persistence API which we will maintain alongside wallet for v1.0. This is less baggage for users and maintainers alike. ### Notes to the reviewers **How breaking are these changes?** Unless if you were implementing your own persistence, then not breaking at all! If you were implementing your own persistence for BDK, the breakages are minimal. The main change is introducing the `initialize` method to persistence traits (which replaces `load`). **Acknowledgements** I came up with the idea of this while responding to @tnull's suggestions on Discord. Unfortunately we cannot fulfill all of his requests. However, I do believe that this will make things easier for our users. ### Changelog notice * Removed the `persist` module in `bdk_chain`. * Added `WalletPersister`/`AsyncWalletPersister` traits and `PersistedWallet` struct to `bdk_wallet`. These are simplified and safer versions of old structs provided by the `persist` module in `bdk_chain`. * Change `.init_sqlite_tables` method to be public on changeset types. `from_sqlite` and `persist_into_sqlite` methods no longer call `.init_sqlite_tables` internally. ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### What is left to do: - [x] Better docs. ACKs for top commit: notmandatory: ACK 340808e Tree-SHA512: 77643196543ad0a741f9ec51de4aad3893c6d608234ad6709c8688043bf1eef1e5e97e71681be0a6b29dec3fa255e2f0e63e08511c79ea4c0a6ef3286653d40c
Description
async postgres support for persistance
Notes to the reviewers
Here I am implementing async postgres via the SQLx crate. Currently there is only synchronous support via the FileStore and rustqlite implementations.
A big issue with this PR is that Rusqlite uses libsqlite3, and so does SQLx but with different versions. Cargo does not allow this, even though it should work, there is currently a bug that the SQLx maintianers showed me that explains this behavior. Nevertheless, including both sqlx and rusqlite in the same workspace will not work - bdk having a strict msrv requirement also does not help (once the fix lands in cargo, it will take time for the msrv of cargo to catch up).
My issues are with the PersistAsyncWith trait, I was unable to implement it. Some guidance would be appreciated.