Add Postgres database#863
Conversation
|
👋 Thanks for assigning @Camillarhi as a reviewer! |
tnull
left a comment
There was a problem hiding this comment.
Took a first high-level look.
Also gates sqlite behind a feature flag, since most tests relied on this, we ended up needing to gate a lot of them behind the flag. Curious on thoughts on how to handle this best
Not sure I'm following? Why do we want to feature-gate tests based on SQLite?
Also tagging @tankyleo as a secondary reviewer here as he has a lot of recent experience with Postgres on VSS Server.
|
|
||
| // An internal runtime we use to avoid any deadlocks we could hit when waiting on async | ||
| // operations to finish from a sync context. | ||
| internal_runtime: Option<tokio::runtime::Runtime>, |
There was a problem hiding this comment.
I think we could avoid using an internal runtime for this and rather just reuse crate::runtime::Runtime, if we wanted. Though, when upstreaming to LDK we'll need to rethink all of this anyways (cf. VssStore upstreaming PR).
There was a problem hiding this comment.
Yeah I just copied VSS to be safe.
There was a problem hiding this comment.
Yeah, let's drop the extra runtime then.
There was a problem hiding this comment.
This seems to be unaddressed? (cc @benthecarman). Or I guess you interpreted 'then' as 'when we upstream'? IMO it's likely unnecessary in this case, so might as well do it now, but let me know if you'd rather keep it for now.
There was a problem hiding this comment.
Ohh missed your other comment, fixed
|
|
||
| /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options | ||
| /// previously configured. | ||
| #[cfg(feature = "sqlite")] |
There was a problem hiding this comment.
Why do we suddenly introduce features? We so far held off and meant to do that in a dedicated PR at some point for this or next release. Is it necessary to make Postgres work?
There was a problem hiding this comment.
okay removed for now
There was a problem hiding this comment.
Seems the postgres feature is still present in the current version?
b5d297e to
e8f478b
Compare
|
Did fixes in follow up commits for ease of review. |
|
🔔 1st Reminder Hey @tankyleo! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @tankyleo! This PR has been waiting for your review. |
tankyleo
left a comment
There was a problem hiding this comment.
Verbose review, please dismiss aggressively :)
|
@tankyleo addressed most of your comments. Lots of docs improvements. Better handling around the db name and creating the db. And did the code clean ups + test improvements you suggested. |
a8589ea to
a43b13b
Compare
|
🔔 1st Reminder Hey @tankyleo! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @tankyleo! This PR has been waiting for your review. |
3bb9810 to
437f11f
Compare
tankyleo
left a comment
There was a problem hiding this comment.
two small nits thank you
69e82d4 to
b373ff3
Compare
|
🔔 1st Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
|
||
| [features] | ||
| default = [] | ||
| postgres = ["dep:tokio-postgres", "dep:native-tls", "dep:postgres-native-tls"] |
There was a problem hiding this comment.
Hmm, we probably want to introduce features even before the next release, but still not a fan of just adding a one-off feature for this.
There was a problem hiding this comment.
Reconsidered offline. Fine to leave for now, for the release we'll change it anyways as part of #900
|
🔔 2nd Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 3rd Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 4th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 5th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 6th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 7th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 8th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 9th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 10th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
|
🔔 11th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
tnull
left a comment
There was a problem hiding this comment.
This needs a minor rebase by now. Also let me know once you looked further into the blocking behavior you saw in the benchmarks (discussed offline)
Yeah so in the payment benchmark (see #915) it currently fails with a postgres backend because we’re hitting the blocking task limit in tokio by using We can fix this by adding a dedicated runtime to the postgres store similar to VSS or by taking the dep Otherwise the real fix is to have |
|
🔔 12th Reminder Hey @Camillarhi! This PR has been waiting for your review. |
Okay, good to hear it was indeed the blocking worker limit. Mind opening an issue for this? We plan to make |
| // keeps the previous value untouched on UPSERT-update; the sequence persists across | ||
| // restarts. | ||
| let sql = format!( | ||
| "CREATE TABLE IF NOT EXISTS {kv_table_name} ( |
There was a problem hiding this comment.
Codex nit:
- [P2] Quote or validate PostgreSQL identifiers — /home/tnull/workspace/ldk-node/src/io/postgres_store/mod.rs:348-348
Because kv_table_name is interpolated directly as an unquoted SQL identifier, a caller-provided table name such as tenant-1, a reserved word, or a schema-qualified name will fail during store setup even though the API accepts an arbitrary String. Quote identifiers safely or reject
unsupported names before formatting them into the table/comment/index SQL.
There was a problem hiding this comment.
Seems now all Postgres tests are failing.
Add a PostgresStore implementation behind the "postgres" feature flag, mirroring the existing SqliteStore. Uses tokio-postgres (async-native) with an internal tokio runtime for the sync KVStoreSync trait, following the VssStore pattern. Includes unit tests, integration tests (channel full cycle and node restart), and a CI workflow that runs both against a PostgreSQL service container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| // fails; otherwise it gets dropped silently. Log it at debug! so a later failure | ||
| // (e.g. an auth error that surfaces only when the pool is built) can be traced | ||
| // back to the real cause. | ||
| log::debug!( |
There was a problem hiding this comment.
Huh, what's this? We're not (always) using log facade in LDK Node. You'll need to give PostgresStore an Arc<Logger> and log towards that using the LDK macros to make sure users will always see the outputs independently of chosen backend.
| let inner = PostgresStoreInner::new(connection_string, db_name, kv_table_name, tls).await?; | ||
| let inner = Arc::new(inner); | ||
| let next_write_version = AtomicU64::new(1); | ||
| let handle = tokio::runtime::Handle::current(); |
There was a problem hiding this comment.
No, please hand in the Arc<Runtime> use that for the blocking tasks. We should also drop the custom block_on helper as it makes things even more confusing. Also note there is a bug here:
- [P2] Build PostgresStore on the configured runtime — /home/tnull/workspace/ldk-node/src/builder.rs:676-677
When set_runtime is used and build_with_postgres_store is called from a different Tokio runtime, Runtime::block_on uses the caller's current runtime instead of the configured handle. PostgresStore::new captures Handle::current() and spawns its connection drivers there, so a node built from
a temporary caller runtime can later run persistence against a dropped runtime rather than the node runtime. Please force construction onto the configured runtime handle.
Add a PostgresStore implementation behind the
postgresfeature flag, mirroring the existingSqliteStore. Usestokio-postgres(async-native) with an internal tokio runtime for the syncKVStoreSynctrait, following theVssStorepattern.Also gates sqlite behind a feature flag, since most tests relied on this, we ended up needing to gate a lot of them behind the flag. Curious on thoughts on how to handle this best