2929//! use ldk_node::Builder;
3030//! use ldk_node::lightning_invoice::Invoice;
3131//! use ldk_node::bitcoin::secp256k1::PublicKey;
32+ //! use ldk_node::bitcoin::Network;
3233//! use std::str::FromStr;
3334//!
3435//! fn main() {
35- //! let node = Builder::new()
36- //! .set_network("testnet")
37- //! .set_esplora_server_url("https://blockstream.info/testnet/api".to_string())
38- //! .build();
36+ //! let mut builder = Builder::new();
37+ //! builder.set_network(Network::Testnet);
38+ //! builder.set_esplora_server_url("https://blockstream.info/testnet/api".to_string());
3939//!
40+ //! let node = builder.build();
4041//! node.start().unwrap();
4142//!
4243//! let _funding_address = node.new_funding_address();
@@ -142,6 +143,8 @@ use bitcoin::hashes::Hash;
142143use bitcoin:: secp256k1:: PublicKey ;
143144use bitcoin:: Network ;
144145
146+ use bip39:: Mnemonic ;
147+
145148use bitcoin:: { Address , BlockHash , OutPoint , Txid } ;
146149
147150use rand:: Rng ;
@@ -150,7 +153,6 @@ use std::convert::TryInto;
150153use std:: default:: Default ;
151154use std:: fs;
152155use std:: net:: SocketAddr ;
153- use std:: str:: FromStr ;
154156use std:: sync:: atomic:: { AtomicBool , Ordering } ;
155157use std:: sync:: { Arc , Mutex , RwLock } ;
156158use std:: time:: { Duration , Instant , SystemTime } ;
@@ -204,7 +206,7 @@ impl Default for Config {
204206enum EntropySourceConfig {
205207 SeedFile ( String ) ,
206208 SeedBytes ( [ u8 ; WALLET_KEYS_SEED_LEN ] ) ,
207- Bip39Mnemonic { mnemonic : bip39 :: Mnemonic , passphrase : Option < String > } ,
209+ Bip39Mnemonic { mnemonic : Mnemonic , passphrase : Option < String > } ,
208210}
209211
210212#[ derive( Debug , Clone ) ]
@@ -215,106 +217,105 @@ enum GossipSourceConfig {
215217
216218/// A builder for an [`Node`] instance, allowing to set some configuration and module choices from
217219/// the getgo.
218- #[ derive( Debug , Clone ) ]
220+ #[ derive( Debug ) ]
219221pub struct Builder {
220- config : Config ,
221- entropy_source_config : Option < EntropySourceConfig > ,
222- gossip_source_config : Option < GossipSourceConfig > ,
222+ config : Mutex < Config > ,
223+ entropy_source_config : Mutex < Option < EntropySourceConfig > > ,
224+ gossip_source_config : Mutex < Option < GossipSourceConfig > > ,
223225}
224226
225227impl Builder {
226228 /// Creates a new builder instance with the default configuration.
227229 pub fn new ( ) -> Self {
228- let config = Config :: default ( ) ;
229- let entropy_source_config = None ;
230- let gossip_source_config = None ;
230+ let config = Mutex :: new ( Config :: default ( ) ) ;
231+ let entropy_source_config = Mutex :: new ( None ) ;
232+ let gossip_source_config = Mutex :: new ( None ) ;
231233 Self { config, entropy_source_config, gossip_source_config }
232234 }
233235
234236 /// Creates a new builder instance from an [`Config`].
235237 pub fn from_config ( config : Config ) -> Self {
236- let entropy_source_config = None ;
237- let gossip_source_config = None ;
238+ let config = Mutex :: new ( config) ;
239+ let entropy_source_config = Mutex :: new ( None ) ;
240+ let gossip_source_config = Mutex :: new ( None ) ;
238241 Self { config, entropy_source_config, gossip_source_config }
239242 }
240243
241244 /// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
242245 ///
243246 /// If the given file does not exist a new random seed file will be generated and
244247 /// stored at the given location.
245- pub fn set_entropy_seed_path ( & mut self , seed_path : String ) -> & mut Self {
246- self . entropy_source_config = Some ( EntropySourceConfig :: SeedFile ( seed_path) ) ;
247- self
248+ pub fn set_entropy_seed_path ( & self , seed_path : String ) {
249+ * self . entropy_source_config . lock ( ) . unwrap ( ) =
250+ Some ( EntropySourceConfig :: SeedFile ( seed_path) ) ;
251+ }
252+
253+ /// Configures the [`Node`] instance to source its wallet entropy from the given 64 seed bytes.
254+ ///
255+ /// **Note:** Panics if the length of the given `seed_bytes` differs from 64.
256+ pub fn set_entropy_seed_bytes ( & self , seed_bytes : Vec < u8 > ) {
257+ if seed_bytes. len ( ) != WALLET_KEYS_SEED_LEN {
258+ panic ! ( "Failed to set seed due to invalid length." ) ;
259+ }
260+ let mut bytes = [ 0u8 ; WALLET_KEYS_SEED_LEN ] ;
261+ bytes. copy_from_slice ( & seed_bytes) ;
262+ * self . entropy_source_config . lock ( ) . unwrap ( ) = Some ( EntropySourceConfig :: SeedBytes ( bytes) ) ;
248263 }
249264
250- /// Configures the [`Node`] instance to source its wallet entropy from the given seed bytes.
251- pub fn set_entropy_seed_bytes ( & mut self , seed_bytes : [ u8 ; WALLET_KEYS_SEED_LEN ] ) -> & mut Self {
252- self . entropy_source_config = Some ( EntropySourceConfig :: SeedBytes ( seed_bytes) ) ;
253- self
265+ /// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
266+ ///
267+ /// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
268+ pub fn set_entropy_bip39_mnemonic ( & self , mnemonic : Mnemonic , passphrase : Option < String > ) {
269+ * self . entropy_source_config . lock ( ) . unwrap ( ) =
270+ Some ( EntropySourceConfig :: Bip39Mnemonic { mnemonic, passphrase } ) ;
254271 }
255272
256273 /// Configures the [`Node`] instance to source its gossip data from the Lightning peer-to-peer
257274 /// network.
258- pub fn set_gossip_source_p2p ( & mut self ) -> & mut Self {
259- self . gossip_source_config = Some ( GossipSourceConfig :: P2PNetwork ) ;
260- self
275+ pub fn set_gossip_source_p2p ( & self ) {
276+ * self . gossip_source_config . lock ( ) . unwrap ( ) = Some ( GossipSourceConfig :: P2PNetwork ) ;
261277 }
262278
263279 /// Configures the [`Node`] instance to source its gossip data from the given RapidGossipSync
264280 /// server.
265- pub fn set_gossip_source_rgs ( & mut self , rgs_server_url : String ) -> & mut Self {
266- self . gossip_source_config = Some ( GossipSourceConfig :: RapidGossipSync ( rgs_server_url) ) ;
267- self
268- }
269-
270- /// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
271- ///
272- /// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
273- pub fn set_entropy_bip39_mnemonic (
274- & mut self , mnemonic : bip39:: Mnemonic , passphrase : Option < String > ,
275- ) -> & mut Self {
276- self . entropy_source_config =
277- Some ( EntropySourceConfig :: Bip39Mnemonic { mnemonic, passphrase } ) ;
278- self
281+ pub fn set_gossip_source_rgs ( & self , rgs_server_url : String ) {
282+ * self . gossip_source_config . lock ( ) . unwrap ( ) =
283+ Some ( GossipSourceConfig :: RapidGossipSync ( rgs_server_url) ) ;
279284 }
280285
281286 /// Sets the used storage directory path.
282287 ///
283288 /// Default: `/tmp/ldk_node/`
284- pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
285- self . config . storage_dir_path = storage_dir_path ;
286- self
289+ pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
290+ let mut config = self . config . lock ( ) . unwrap ( ) ;
291+ config . storage_dir_path = storage_dir_path ;
287292 }
288293
289294 /// Sets the Esplora server URL.
290295 ///
291296 /// Default: `https://blockstream.info/api`
292- pub fn set_esplora_server_url ( & mut self , esplora_server_url : String ) -> & mut Self {
293- self . config . esplora_server_url = esplora_server_url ;
294- self
297+ pub fn set_esplora_server_url ( & self , esplora_server_url : String ) {
298+ let mut config = self . config . lock ( ) . unwrap ( ) ;
299+ config . esplora_server_url = esplora_server_url ;
295300 }
296301
297302 /// Sets the Bitcoin network used.
298- ///
299- /// Options: `mainnet`/`bitcoin`, `testnet`, `regtest`, `signet`
300- ///
301- /// Default: `regtest`
302- pub fn set_network ( & mut self , network : & str ) -> & mut Self {
303- self . config . network = Network :: from_str ( network) . unwrap_or ( Network :: Regtest ) ;
304- self
303+ pub fn set_network ( & self , network : Network ) {
304+ let mut config = self . config . lock ( ) . unwrap ( ) ;
305+ config. network = network;
305306 }
306307
307308 /// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
308309 ///
309310 /// Default: `0.0.0.0:9735`
310- pub fn set_listening_address ( & mut self , listening_address : SocketAddr ) -> & mut Self {
311- self . config . listening_address = Some ( listening_address ) ;
312- self
311+ pub fn set_listening_address ( & self , listening_address : SocketAddr ) {
312+ let mut config = self . config . lock ( ) . unwrap ( ) ;
313+ config . listening_address = Some ( listening_address ) ;
313314 }
314315
315316 /// Builds a [`Node`] instance according to the options previously configured.
316317 pub fn build ( & self ) -> Arc < Node > {
317- let config = Arc :: new ( self . config . clone ( ) ) ;
318+ let config = Arc :: new ( self . config . lock ( ) . unwrap ( ) . clone ( ) ) ;
318319
319320 let ldk_data_dir = format ! ( "{}/ldk" , config. storage_dir_path) ;
320321 fs:: create_dir_all ( ldk_data_dir. clone ( ) ) . expect ( "Failed to create LDK data directory" ) ;
@@ -327,7 +328,9 @@ impl Builder {
327328 let logger = Arc :: new ( FilesystemLogger :: new ( log_file_path) ) ;
328329
329330 // Initialize the on-chain wallet and chain access
330- let seed_bytes = if let Some ( entropy_source_config) = & self . entropy_source_config {
331+ let seed_bytes = if let Some ( entropy_source_config) =
332+ & * self . entropy_source_config . lock ( ) . unwrap ( )
333+ {
331334 // Use the configured entropy source, if the user set one.
332335 match entropy_source_config {
333336 EntropySourceConfig :: SeedBytes ( bytes) => bytes. clone ( ) ,
@@ -534,8 +537,9 @@ impl Builder {
534537
535538 // Initialize the GossipSource
536539 // Use the configured gossip source, if the user set one, otherwise default to P2PNetwork.
540+ let gossip_source_config_lock = self . gossip_source_config . lock ( ) . unwrap ( ) ;
537541 let gossip_source_config =
538- self . gossip_source_config . as_ref ( ) . unwrap_or ( & GossipSourceConfig :: P2PNetwork ) ;
542+ gossip_source_config_lock . as_ref ( ) . unwrap_or ( & GossipSourceConfig :: P2PNetwork ) ;
539543
540544 let gossip_source = match gossip_source_config {
541545 GossipSourceConfig :: P2PNetwork => {
0 commit comments