@@ -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 [`FilesystemStoreV2`] backend and according to the options
648691 /// previously configured.
649692 ///
@@ -789,18 +832,27 @@ impl NodeBuilder {
789832 self . build_with_store_and_logger ( node_entropy, kv_store, logger)
790833 }
791834
792- fn build_with_store_and_logger < S : SyncAndAsyncKVStore + Send + Sync + ' static > (
793- & self , node_entropy : NodeEntropy , kv_store : S , logger : Arc < Logger > ,
794- ) -> Result < Node , BuildError > {
795- let runtime = if let Some ( handle) = self . runtime_handle . as_ref ( ) {
796- Arc :: new ( Runtime :: with_handle ( handle. clone ( ) , Arc :: clone ( & logger) ) )
835+ fn setup_runtime ( & self , logger : & Arc < Logger > ) -> Result < Arc < Runtime > , BuildError > {
836+ if let Some ( handle) = self . runtime_handle . as_ref ( ) {
837+ Ok ( Arc :: new ( Runtime :: with_handle ( handle. clone ( ) , Arc :: clone ( logger) ) ) )
797838 } else {
798- Arc :: new ( Runtime :: new ( Arc :: clone ( & logger) ) . map_err ( |e| {
839+ Ok ( Arc :: new ( Runtime :: new ( Arc :: clone ( logger) ) . map_err ( |e| {
799840 log_error ! ( logger, "Failed to setup tokio runtime: {}" , e) ;
800841 BuildError :: RuntimeSetupFailed
801- } ) ?)
802- } ;
842+ } ) ?) )
843+ }
844+ }
845+
846+ fn build_with_store_and_logger < S : SyncAndAsyncKVStore + Send + Sync + ' static > (
847+ & self , node_entropy : NodeEntropy , kv_store : S , logger : Arc < Logger > ,
848+ ) -> Result < Node , BuildError > {
849+ let runtime = self . setup_runtime ( & logger) ?;
850+ self . build_with_store_runtime_and_logger ( node_entropy, kv_store, runtime, logger)
851+ }
803852
853+ fn build_with_store_runtime_and_logger < S : SyncAndAsyncKVStore + Send + Sync + ' static > (
854+ & self , node_entropy : NodeEntropy , kv_store : S , runtime : Arc < Runtime > , logger : Arc < Logger > ,
855+ ) -> Result < Node , BuildError > {
804856 let seed_bytes = node_entropy. to_seed_bytes ( ) ;
805857 let config = Arc :: new ( self . config . clone ( ) ) ;
806858
@@ -1116,6 +1168,58 @@ impl ArcedNodeBuilder {
11161168 self . inner . read ( ) . expect ( "lock" ) . build ( * node_entropy) . map ( Arc :: new)
11171169 }
11181170
1171+ /// Builds a [`Node`] instance with a [PostgreSQL] backend and according to the options
1172+ /// previously configured.
1173+ ///
1174+ /// Connects to the PostgreSQL database at the given `connection_string`, e.g.,
1175+ /// `"postgres://user:password@localhost/ldk_db"`.
1176+ ///
1177+ /// The given `db_name` will be used or default to
1178+ /// [`DEFAULT_DB_NAME`](io::postgres_store::DEFAULT_DB_NAME). The `connection_string` must
1179+ /// not include a `dbname` when `db_name` is set, providing both is an error. The database
1180+ /// will be created automatically if it doesn't already exist. The initial connection is
1181+ /// made to the target database, and if it fails we fall back to the default `postgres`
1182+ /// database to create it.
1183+ ///
1184+ /// The given `kv_table_name` will be used or default to
1185+ /// [`DEFAULT_KV_TABLE_NAME`](io::postgres_store::DEFAULT_KV_TABLE_NAME).
1186+ ///
1187+ /// If `certificate_pem` is `Some`, TLS will be used for database connections and the
1188+ /// provided PEM-encoded CA certificate will be added to the system's default root
1189+ /// certificates (it does not replace them). If `certificate_pem` is `None`, connections
1190+ /// will be unencrypted.
1191+ ///
1192+ /// [PostgreSQL]: https://www.postgresql.org
1193+ #[ cfg( feature = "postgres" ) ]
1194+ pub fn build_with_postgres_store (
1195+ & self , node_entropy : Arc < NodeEntropy > , connection_string : String , db_name : Option < String > ,
1196+ kv_table_name : Option < String > , certificate_pem : Option < String > ,
1197+ ) -> Result < Arc < Node > , BuildError > {
1198+ self . inner
1199+ . read ( )
1200+ . unwrap ( )
1201+ . build_with_postgres_store (
1202+ * node_entropy,
1203+ connection_string,
1204+ db_name,
1205+ kv_table_name,
1206+ certificate_pem,
1207+ )
1208+ . map ( Arc :: new)
1209+ }
1210+
1211+ /// Builds a [`Node`] instance with a [PostgreSQL] backend and according to the options
1212+ /// previously configured.
1213+ ///
1214+ /// This requires the `postgres` crate feature.
1215+ #[ cfg( not( feature = "postgres" ) ) ]
1216+ pub fn build_with_postgres_store (
1217+ & self , _node_entropy : Arc < NodeEntropy > , _connection_string : String ,
1218+ _db_name : Option < String > , _kv_table_name : Option < String > , _certificate_pem : Option < String > ,
1219+ ) -> Result < Arc < Node > , BuildError > {
1220+ Err ( BuildError :: KVStoreSetupFailed )
1221+ }
1222+
11191223 /// Builds a [`Node`] instance with a [`FilesystemStoreV2`] backend and according to the options
11201224 /// previously configured.
11211225 pub fn build_with_fs_store (
0 commit comments