29
29
//! use ldk_node::{Builder, NetAddress};
30
30
//! use ldk_node::lightning_invoice::Invoice;
31
31
//! use ldk_node::bitcoin::secp256k1::PublicKey;
32
+ //! use ldk_node::bitcoin::Network;
32
33
//! use std::str::FromStr;
33
34
//!
34
35
//! 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());
39
39
//!
40
+ //! let node = builder.build();
40
41
//! node.start().unwrap();
41
42
//!
42
43
//! let _funding_address = node.new_funding_address();
@@ -144,6 +145,8 @@ use bitcoin::hashes::Hash;
144
145
use bitcoin:: secp256k1:: PublicKey ;
145
146
use bitcoin:: Network ;
146
147
148
+ use bip39:: Mnemonic ;
149
+
147
150
use bitcoin:: { Address , BlockHash , OutPoint , Txid } ;
148
151
149
152
use rand:: Rng ;
@@ -199,7 +202,7 @@ impl Default for Config {
199
202
storage_dir_path : "/tmp/ldk_node/" . to_string ( ) ,
200
203
esplora_server_url : "http://localhost:3002" . to_string ( ) ,
201
204
network : Network :: Regtest ,
202
- listening_address : Some ( "0.0.0.0:9735" . parse ( ) . unwrap ( ) ) ,
205
+ listening_address : Some ( NetAddress :: from_str ( "0.0.0.0:9735" ) . unwrap ( ) ) ,
203
206
default_cltv_expiry_delta : 144 ,
204
207
}
205
208
}
@@ -209,7 +212,7 @@ impl Default for Config {
209
212
enum EntropySourceConfig {
210
213
SeedFile ( String ) ,
211
214
SeedBytes ( [ u8 ; WALLET_KEYS_SEED_LEN ] ) ,
212
- Bip39Mnemonic { mnemonic : bip39 :: Mnemonic , passphrase : Option < String > } ,
215
+ Bip39Mnemonic { mnemonic : Mnemonic , passphrase : Option < String > } ,
213
216
}
214
217
215
218
#[ derive( Debug , Clone ) ]
@@ -220,106 +223,105 @@ enum GossipSourceConfig {
220
223
221
224
/// A builder for an [`Node`] instance, allowing to set some configuration and module choices from
222
225
/// the getgo.
223
- #[ derive( Debug , Clone ) ]
226
+ #[ derive( Debug ) ]
224
227
pub struct Builder {
225
- config : Config ,
226
- entropy_source_config : Option < EntropySourceConfig > ,
227
- gossip_source_config : Option < GossipSourceConfig > ,
228
+ config : Mutex < Config > ,
229
+ entropy_source_config : Mutex < Option < EntropySourceConfig > > ,
230
+ gossip_source_config : Mutex < Option < GossipSourceConfig > > ,
228
231
}
229
232
230
233
impl Builder {
231
234
/// Creates a new builder instance with the default configuration.
232
235
pub fn new ( ) -> Self {
233
- let config = Config :: default ( ) ;
234
- let entropy_source_config = None ;
235
- let gossip_source_config = None ;
236
+ let config = Mutex :: new ( Config :: default ( ) ) ;
237
+ let entropy_source_config = Mutex :: new ( None ) ;
238
+ let gossip_source_config = Mutex :: new ( None ) ;
236
239
Self { config, entropy_source_config, gossip_source_config }
237
240
}
238
241
239
242
/// Creates a new builder instance from an [`Config`].
240
243
pub fn from_config ( config : Config ) -> Self {
241
- let entropy_source_config = None ;
242
- let gossip_source_config = None ;
244
+ let config = Mutex :: new ( config) ;
245
+ let entropy_source_config = Mutex :: new ( None ) ;
246
+ let gossip_source_config = Mutex :: new ( None ) ;
243
247
Self { config, entropy_source_config, gossip_source_config }
244
248
}
245
249
246
250
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
247
251
///
248
252
/// If the given file does not exist a new random seed file will be generated and
249
253
/// stored at the given location.
250
- pub fn set_entropy_seed_path ( & mut self , seed_path : String ) -> & mut Self {
251
- self . entropy_source_config = Some ( EntropySourceConfig :: SeedFile ( seed_path) ) ;
252
- self
254
+ pub fn set_entropy_seed_path ( & self , seed_path : String ) {
255
+ * self . entropy_source_config . lock ( ) . unwrap ( ) =
256
+ Some ( EntropySourceConfig :: SeedFile ( seed_path) ) ;
257
+ }
258
+
259
+ /// Configures the [`Node`] instance to source its wallet entropy from the given 64 seed bytes.
260
+ ///
261
+ /// **Note:** Panics if the length of the given `seed_bytes` differs from 64.
262
+ pub fn set_entropy_seed_bytes ( & self , seed_bytes : Vec < u8 > ) {
263
+ if seed_bytes. len ( ) != WALLET_KEYS_SEED_LEN {
264
+ panic ! ( "Failed to set seed due to invalid length." ) ;
265
+ }
266
+ let mut bytes = [ 0u8 ; WALLET_KEYS_SEED_LEN ] ;
267
+ bytes. copy_from_slice ( & seed_bytes) ;
268
+ * self . entropy_source_config . lock ( ) . unwrap ( ) = Some ( EntropySourceConfig :: SeedBytes ( bytes) ) ;
253
269
}
254
270
255
- /// Configures the [`Node`] instance to source its wallet entropy from the given seed bytes.
256
- pub fn set_entropy_seed_bytes ( & mut self , seed_bytes : [ u8 ; WALLET_KEYS_SEED_LEN ] ) -> & mut Self {
257
- self . entropy_source_config = Some ( EntropySourceConfig :: SeedBytes ( seed_bytes) ) ;
258
- self
271
+ /// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
272
+ ///
273
+ /// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
274
+ pub fn set_entropy_bip39_mnemonic ( & self , mnemonic : Mnemonic , passphrase : Option < String > ) {
275
+ * self . entropy_source_config . lock ( ) . unwrap ( ) =
276
+ Some ( EntropySourceConfig :: Bip39Mnemonic { mnemonic, passphrase } ) ;
259
277
}
260
278
261
279
/// Configures the [`Node`] instance to source its gossip data from the Lightning peer-to-peer
262
280
/// network.
263
- pub fn set_gossip_source_p2p ( & mut self ) -> & mut Self {
264
- self . gossip_source_config = Some ( GossipSourceConfig :: P2PNetwork ) ;
265
- self
281
+ pub fn set_gossip_source_p2p ( & self ) {
282
+ * self . gossip_source_config . lock ( ) . unwrap ( ) = Some ( GossipSourceConfig :: P2PNetwork ) ;
266
283
}
267
284
268
285
/// Configures the [`Node`] instance to source its gossip data from the given RapidGossipSync
269
286
/// server.
270
- pub fn set_gossip_source_rgs ( & mut self , rgs_server_url : String ) -> & mut Self {
271
- self . gossip_source_config = Some ( GossipSourceConfig :: RapidGossipSync ( rgs_server_url) ) ;
272
- self
273
- }
274
-
275
- /// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
276
- ///
277
- /// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
278
- pub fn set_entropy_bip39_mnemonic (
279
- & mut self , mnemonic : bip39:: Mnemonic , passphrase : Option < String > ,
280
- ) -> & mut Self {
281
- self . entropy_source_config =
282
- Some ( EntropySourceConfig :: Bip39Mnemonic { mnemonic, passphrase } ) ;
283
- self
287
+ pub fn set_gossip_source_rgs ( & self , rgs_server_url : String ) {
288
+ * self . gossip_source_config . lock ( ) . unwrap ( ) =
289
+ Some ( GossipSourceConfig :: RapidGossipSync ( rgs_server_url) ) ;
284
290
}
285
291
286
292
/// Sets the used storage directory path.
287
293
///
288
294
/// Default: `/tmp/ldk_node/`
289
- pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
290
- self . config . storage_dir_path = storage_dir_path ;
291
- self
295
+ pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
296
+ let mut config = self . config . lock ( ) . unwrap ( ) ;
297
+ config . storage_dir_path = storage_dir_path ;
292
298
}
293
299
294
300
/// Sets the Esplora server URL.
295
301
///
296
302
/// Default: `https://blockstream.info/api`
297
- pub fn set_esplora_server_url ( & mut self , esplora_server_url : String ) -> & mut Self {
298
- self . config . esplora_server_url = esplora_server_url ;
299
- self
303
+ pub fn set_esplora_server_url ( & self , esplora_server_url : String ) {
304
+ let mut config = self . config . lock ( ) . unwrap ( ) ;
305
+ config . esplora_server_url = esplora_server_url ;
300
306
}
301
307
302
308
/// Sets the Bitcoin network used.
303
- ///
304
- /// Options: `mainnet`/`bitcoin`, `testnet`, `regtest`, `signet`
305
- ///
306
- /// Default: `regtest`
307
- pub fn set_network ( & mut self , network : & str ) -> & mut Self {
308
- self . config . network = Network :: from_str ( network) . unwrap_or ( Network :: Regtest ) ;
309
- self
309
+ pub fn set_network ( & self , network : Network ) {
310
+ let mut config = self . config . lock ( ) . unwrap ( ) ;
311
+ config. network = network;
310
312
}
311
313
312
314
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
313
315
///
314
316
/// Default: `0.0.0.0:9735`
315
- pub fn set_listening_address ( & mut self , listening_address : NetAddress ) -> & mut Self {
316
- self . config . listening_address = Some ( listening_address ) ;
317
- self
317
+ pub fn set_listening_address ( & self , listening_address : NetAddress ) {
318
+ let mut config = self . config . lock ( ) . unwrap ( ) ;
319
+ config . listening_address = Some ( listening_address ) ;
318
320
}
319
321
320
322
/// Builds a [`Node`] instance according to the options previously configured.
321
323
pub fn build ( & self ) -> Arc < Node > {
322
- let config = Arc :: new ( self . config . clone ( ) ) ;
324
+ let config = Arc :: new ( self . config . lock ( ) . unwrap ( ) . clone ( ) ) ;
323
325
324
326
let ldk_data_dir = format ! ( "{}/ldk" , config. storage_dir_path) ;
325
327
fs:: create_dir_all ( ldk_data_dir. clone ( ) ) . expect ( "Failed to create LDK data directory" ) ;
@@ -332,7 +334,9 @@ impl Builder {
332
334
let logger = Arc :: new ( FilesystemLogger :: new ( log_file_path) ) ;
333
335
334
336
// Initialize the on-chain wallet and chain access
335
- let seed_bytes = if let Some ( entropy_source_config) = & self . entropy_source_config {
337
+ let seed_bytes = if let Some ( entropy_source_config) =
338
+ & * self . entropy_source_config . lock ( ) . unwrap ( )
339
+ {
336
340
// Use the configured entropy source, if the user set one.
337
341
match entropy_source_config {
338
342
EntropySourceConfig :: SeedBytes ( bytes) => bytes. clone ( ) ,
@@ -539,8 +543,9 @@ impl Builder {
539
543
540
544
// Initialize the GossipSource
541
545
// Use the configured gossip source, if the user set one, otherwise default to P2PNetwork.
546
+ let gossip_source_config_lock = self . gossip_source_config . lock ( ) . unwrap ( ) ;
542
547
let gossip_source_config =
543
- self . gossip_source_config . as_ref ( ) . unwrap_or ( & GossipSourceConfig :: P2PNetwork ) ;
548
+ gossip_source_config_lock . as_ref ( ) . unwrap_or ( & GossipSourceConfig :: P2PNetwork ) ;
544
549
545
550
let gossip_source = match gossip_source_config {
546
551
GossipSourceConfig :: P2PNetwork => {
0 commit comments