@@ -644,6 +644,49 @@ impl NodeBuilder {
644644 self . build_with_store_and_logger ( node_entropy, kv_store, logger)
645645 }
646646
647+ /// Builds a [`Node`] instance with a [PostgreSQL] backend and according to the options
648+ /// previously configured.
649+ ///
650+ /// Connects to the PostgreSQL database at the given `connection_string`, e.g.,
651+ /// `"postgres://user:password@localhost/ldk_db"`.
652+ ///
653+ /// The given `db_name` will be used or default to
654+ /// [`DEFAULT_DB_NAME`](io::postgres_store::DEFAULT_DB_NAME). The `connection_string` must
655+ /// not include a `dbname` when `db_name` is set, providing both is an error. The database
656+ /// will be created automatically if it doesn't already exist. The initial connection is
657+ /// made to the target database, and if it fails we fall back to the default `postgres`
658+ /// database to create it.
659+ ///
660+ /// The given `kv_table_name` will be used or default to
661+ /// [`DEFAULT_KV_TABLE_NAME`](io::postgres_store::DEFAULT_KV_TABLE_NAME).
662+ ///
663+ /// If `certificate_pem` is `Some`, TLS will be used for database connections and the
664+ /// provided PEM-encoded CA certificate will be added to the system's default root
665+ /// certificates (it does not replace them). If `certificate_pem` is `None`, connections
666+ /// will be unencrypted.
667+ ///
668+ /// [PostgreSQL]: https://www.postgresql.org
669+ #[ cfg( feature = "postgres" ) ]
670+ pub fn build_with_postgres_store (
671+ & self , node_entropy : NodeEntropy , connection_string : String , db_name : Option < String > ,
672+ kv_table_name : Option < String > , certificate_pem : Option < String > ,
673+ ) -> Result < Node , BuildError > {
674+ let logger = setup_logger ( & self . log_writer_config , & self . config ) ?;
675+ let runtime = self . setup_runtime ( & logger) ?;
676+ let kv_store = runtime
677+ . block_on ( io:: postgres_store:: PostgresStore :: new (
678+ connection_string,
679+ db_name,
680+ kv_table_name,
681+ certificate_pem,
682+ ) )
683+ . map_err ( |e| {
684+ log_error ! ( logger, "Failed to set up Postgres store: {e}" ) ;
685+ BuildError :: KVStoreSetupFailed
686+ } ) ?;
687+ self . build_with_store_runtime_and_logger ( node_entropy, kv_store, runtime, logger)
688+ }
689+
647690 /// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
648691 /// previously configured.
649692 pub fn build_with_fs_store ( & self , node_entropy : NodeEntropy ) -> Result < Node , BuildError > {
@@ -788,18 +831,27 @@ impl NodeBuilder {
788831 self . build_with_store_and_logger ( node_entropy, kv_store, logger)
789832 }
790833
791- fn build_with_store_and_logger < S : SyncAndAsyncKVStore + Send + Sync + ' static > (
792- & self , node_entropy : NodeEntropy , kv_store : S , logger : Arc < Logger > ,
793- ) -> Result < Node , BuildError > {
794- let runtime = if let Some ( handle) = self . runtime_handle . as_ref ( ) {
795- Arc :: new ( Runtime :: with_handle ( handle. clone ( ) , Arc :: clone ( & logger) ) )
834+ fn setup_runtime ( & self , logger : & Arc < Logger > ) -> Result < Arc < Runtime > , BuildError > {
835+ if let Some ( handle) = self . runtime_handle . as_ref ( ) {
836+ Ok ( Arc :: new ( Runtime :: with_handle ( handle. clone ( ) , Arc :: clone ( logger) ) ) )
796837 } else {
797- Arc :: new ( Runtime :: new ( Arc :: clone ( & logger) ) . map_err ( |e| {
838+ Ok ( Arc :: new ( Runtime :: new ( Arc :: clone ( logger) ) . map_err ( |e| {
798839 log_error ! ( logger, "Failed to setup tokio runtime: {}" , e) ;
799840 BuildError :: RuntimeSetupFailed
800- } ) ?)
801- } ;
841+ } ) ?) )
842+ }
843+ }
844+
845+ fn build_with_store_and_logger < S : SyncAndAsyncKVStore + Send + Sync + ' static > (
846+ & self , node_entropy : NodeEntropy , kv_store : S , logger : Arc < Logger > ,
847+ ) -> Result < Node , BuildError > {
848+ let runtime = self . setup_runtime ( & logger) ?;
849+ self . build_with_store_runtime_and_logger ( node_entropy, kv_store, runtime, logger)
850+ }
802851
852+ fn build_with_store_runtime_and_logger < S : SyncAndAsyncKVStore + Send + Sync + ' static > (
853+ & self , node_entropy : NodeEntropy , kv_store : S , runtime : Arc < Runtime > , logger : Arc < Logger > ,
854+ ) -> Result < Node , BuildError > {
803855 let seed_bytes = node_entropy. to_seed_bytes ( ) ;
804856 let config = Arc :: new ( self . config . clone ( ) ) ;
805857
@@ -1115,6 +1167,58 @@ impl ArcedNodeBuilder {
11151167 self . inner . read ( ) . expect ( "lock" ) . build ( * node_entropy) . map ( Arc :: new)
11161168 }
11171169
1170+ /// Builds a [`Node`] instance with a [PostgreSQL] backend and according to the options
1171+ /// previously configured.
1172+ ///
1173+ /// Connects to the PostgreSQL database at the given `connection_string`, e.g.,
1174+ /// `"postgres://user:password@localhost/ldk_db"`.
1175+ ///
1176+ /// The given `db_name` will be used or default to
1177+ /// [`DEFAULT_DB_NAME`](io::postgres_store::DEFAULT_DB_NAME). The `connection_string` must
1178+ /// not include a `dbname` when `db_name` is set, providing both is an error. The database
1179+ /// will be created automatically if it doesn't already exist. The initial connection is
1180+ /// made to the target database, and if it fails we fall back to the default `postgres`
1181+ /// database to create it.
1182+ ///
1183+ /// The given `kv_table_name` will be used or default to
1184+ /// [`DEFAULT_KV_TABLE_NAME`](io::postgres_store::DEFAULT_KV_TABLE_NAME).
1185+ ///
1186+ /// If `certificate_pem` is `Some`, TLS will be used for database connections and the
1187+ /// provided PEM-encoded CA certificate will be added to the system's default root
1188+ /// certificates (it does not replace them). If `certificate_pem` is `None`, connections
1189+ /// will be unencrypted.
1190+ ///
1191+ /// [PostgreSQL]: https://www.postgresql.org
1192+ #[ cfg( feature = "postgres" ) ]
1193+ pub fn build_with_postgres_store (
1194+ & self , node_entropy : Arc < NodeEntropy > , connection_string : String , db_name : Option < String > ,
1195+ kv_table_name : Option < String > , certificate_pem : Option < String > ,
1196+ ) -> Result < Arc < Node > , BuildError > {
1197+ self . inner
1198+ . read ( )
1199+ . unwrap ( )
1200+ . build_with_postgres_store (
1201+ * node_entropy,
1202+ connection_string,
1203+ db_name,
1204+ kv_table_name,
1205+ certificate_pem,
1206+ )
1207+ . map ( Arc :: new)
1208+ }
1209+
1210+ /// Builds a [`Node`] instance with a [PostgreSQL] backend and according to the options
1211+ /// previously configured.
1212+ ///
1213+ /// This requires the `postgres` crate feature.
1214+ #[ cfg( not( feature = "postgres" ) ) ]
1215+ pub fn build_with_postgres_store (
1216+ & self , _node_entropy : Arc < NodeEntropy > , _connection_string : String ,
1217+ _db_name : Option < String > , _kv_table_name : Option < String > , _certificate_pem : Option < String > ,
1218+ ) -> Result < Arc < Node > , BuildError > {
1219+ Err ( BuildError :: KVStoreSetupFailed )
1220+ }
1221+
11181222 /// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
11191223 /// previously configured.
11201224 pub fn build_with_fs_store (
0 commit comments