35
35
//! fn main() {
36
36
//! let mut builder = Builder::new();
37
37
//! builder.set_network(Network::Testnet);
38
- //! builder.set_esplora_server_url ("https://blockstream.info/testnet/api".to_string());
38
+ //! builder.set_esplora_server ("https://blockstream.info/testnet/api".to_string());
39
39
//!
40
40
//! let node = builder.build();
41
41
//! node.start().unwrap();
@@ -155,13 +155,19 @@ use std::convert::TryInto;
155
155
use std:: default:: Default ;
156
156
use std:: fs;
157
157
use std:: net:: ToSocketAddrs ;
158
- use std:: str:: FromStr ;
159
158
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
160
159
use std:: sync:: { Arc , Mutex , RwLock } ;
161
160
use std:: time:: { Duration , Instant , SystemTime } ;
162
161
163
162
uniffi:: include_scaffolding!( "ldk_node" ) ;
164
163
164
+ // Config defaults
165
+ const DEFAULT_STORAGE_DIR_PATH : & str = "/tmp/ldk_node/" ;
166
+ const DEFAULT_NETWORK : Network = Network :: Bitcoin ;
167
+ const DEFAULT_LISTENING_ADDR : & str = "0.0.0.0:9735" ;
168
+ const DEFAULT_CLTV_EXPIRY_DELTA : u32 = 144 ;
169
+ const DEFAULT_ESPLORA_SERVER_URL : & str = "https://blockstream.info/api" ;
170
+
165
171
// The 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
166
172
// number of blocks after which BDK stops looking for scripts belonging to the wallet.
167
173
const BDK_CLIENT_STOP_GAP : usize = 20 ;
@@ -183,11 +189,19 @@ const WALLET_KEYS_SEED_LEN: usize = 64;
183
189
184
190
#[ derive( Debug , Clone ) ]
185
191
/// Represents the configuration of an [`Node`] instance.
192
+ ///
193
+ /// ### Defaults
194
+ ///
195
+ /// | Parameter | Value |
196
+ /// |-----------------------------|------------------|
197
+ /// | `storage_dir_path` | /tmp/ldk_node/ |
198
+ /// | `network` | Network::Bitcoin |
199
+ /// | `listening_address` | 0.0.0.0:9735 |
200
+ /// | `default_cltv_expiry_delta` | 144 |
201
+ ///
186
202
pub struct Config {
187
203
/// The path where the underlying LDK and BDK persist their data.
188
204
pub storage_dir_path : String ,
189
- /// The URL of the utilized Esplora server.
190
- pub esplora_server_url : String ,
191
205
/// The used Bitcoin network.
192
206
pub network : Network ,
193
207
/// The IP address and TCP port the node will listen on.
@@ -199,15 +213,19 @@ pub struct Config {
199
213
impl Default for Config {
200
214
fn default ( ) -> Self {
201
215
Self {
202
- storage_dir_path : "/tmp/ldk_node/" . to_string ( ) ,
203
- esplora_server_url : "http://localhost:3002" . to_string ( ) ,
204
- network : Network :: Regtest ,
205
- listening_address : Some ( NetAddress :: from_str ( "0.0.0.0:9735" ) . unwrap ( ) ) ,
206
- default_cltv_expiry_delta : 144 ,
216
+ storage_dir_path : DEFAULT_STORAGE_DIR_PATH . to_string ( ) ,
217
+ network : DEFAULT_NETWORK ,
218
+ listening_address : Some ( DEFAULT_LISTENING_ADDR . parse ( ) . unwrap ( ) ) ,
219
+ default_cltv_expiry_delta : DEFAULT_CLTV_EXPIRY_DELTA ,
207
220
}
208
221
}
209
222
}
210
223
224
+ #[ derive( Debug , Clone ) ]
225
+ enum ChainDataSourceConfig {
226
+ Esplora ( String ) ,
227
+ }
228
+
211
229
#[ derive( Debug , Clone ) ]
212
230
enum EntropySourceConfig {
213
231
SeedFile ( String ) ,
@@ -223,9 +241,15 @@ enum GossipSourceConfig {
223
241
224
242
/// A builder for an [`Node`] instance, allowing to set some configuration and module choices from
225
243
/// the getgo.
244
+ ///
245
+ /// ### Defaults
246
+ /// - Chain data is sourced from the Esplora endpoint `https://blockstream.info/api`
247
+ /// - Wallet entropy is sourced from a `keys_seed` file located under [`Config::storage_dir_path`]
248
+ /// - Gossip data is sourced via the peer-to-peer network
226
249
#[ derive( Debug ) ]
227
250
pub struct Builder {
228
251
config : Mutex < Config > ,
252
+ chain_data_source_config : Mutex < Option < ChainDataSourceConfig > > ,
229
253
entropy_source_config : Mutex < Option < EntropySourceConfig > > ,
230
254
gossip_source_config : Mutex < Option < GossipSourceConfig > > ,
231
255
}
@@ -234,17 +258,19 @@ impl Builder {
234
258
/// Creates a new builder instance with the default configuration.
235
259
pub fn new ( ) -> Self {
236
260
let config = Mutex :: new ( Config :: default ( ) ) ;
261
+ let chain_data_source_config = Mutex :: new ( None ) ;
237
262
let entropy_source_config = Mutex :: new ( None ) ;
238
263
let gossip_source_config = Mutex :: new ( None ) ;
239
- Self { config, entropy_source_config, gossip_source_config }
264
+ Self { config, chain_data_source_config , entropy_source_config, gossip_source_config }
240
265
}
241
266
242
267
/// Creates a new builder instance from an [`Config`].
243
268
pub fn from_config ( config : Config ) -> Self {
244
269
let config = Mutex :: new ( config) ;
270
+ let chain_data_source_config = Mutex :: new ( None ) ;
245
271
let entropy_source_config = Mutex :: new ( None ) ;
246
272
let gossip_source_config = Mutex :: new ( None ) ;
247
- Self { config, entropy_source_config, gossip_source_config }
273
+ Self { config, chain_data_source_config , entropy_source_config, gossip_source_config }
248
274
}
249
275
250
276
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
@@ -276,6 +302,12 @@ impl Builder {
276
302
Some ( EntropySourceConfig :: Bip39Mnemonic { mnemonic, passphrase } ) ;
277
303
}
278
304
305
+ /// Configures the [`Node`] instance to source its chain data from the given Esplora server.
306
+ pub fn set_esplora_server ( & self , esplora_server_url : String ) {
307
+ * self . chain_data_source_config . lock ( ) . unwrap ( ) =
308
+ Some ( ChainDataSourceConfig :: Esplora ( esplora_server_url) ) ;
309
+ }
310
+
279
311
/// Configures the [`Node`] instance to source its gossip data from the Lightning peer-to-peer
280
312
/// network.
281
313
pub fn set_gossip_source_p2p ( & self ) {
@@ -290,30 +322,18 @@ impl Builder {
290
322
}
291
323
292
324
/// Sets the used storage directory path.
293
- ///
294
- /// Default: `/tmp/ldk_node/`
295
325
pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
296
326
let mut config = self . config . lock ( ) . unwrap ( ) ;
297
327
config. storage_dir_path = storage_dir_path;
298
328
}
299
329
300
- /// Sets the Esplora server URL.
301
- ///
302
- /// Default: `https://blockstream.info/api`
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;
306
- }
307
-
308
330
/// Sets the Bitcoin network used.
309
331
pub fn set_network ( & self , network : Network ) {
310
332
let mut config = self . config . lock ( ) . unwrap ( ) ;
311
333
config. network = network;
312
334
}
313
335
314
336
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
315
- ///
316
- /// Default: `0.0.0.0:9735`
317
337
pub fn set_listening_address ( & self , listening_address : NetAddress ) {
318
338
let mut config = self . config . lock ( ) . unwrap ( ) ;
319
339
config. listening_address = Some ( listening_address) ;
@@ -376,14 +396,30 @@ impl Builder {
376
396
)
377
397
. expect ( "Failed to set up on-chain wallet" ) ;
378
398
379
- let tx_sync = Arc :: new ( EsploraSyncClient :: new (
380
- config. esplora_server_url . clone ( ) ,
381
- Arc :: clone ( & logger) ,
382
- ) ) ;
383
-
384
- let blockchain =
385
- EsploraBlockchain :: from_client ( tx_sync. client ( ) . clone ( ) , BDK_CLIENT_STOP_GAP )
386
- . with_concurrency ( BDK_CLIENT_CONCURRENCY ) ;
399
+ let ( blockchain, tx_sync) = if let Some ( chain_data_source_config) =
400
+ & * self . chain_data_source_config . lock ( ) . unwrap ( )
401
+ {
402
+ match chain_data_source_config {
403
+ ChainDataSourceConfig :: Esplora ( server_url) => {
404
+ let tx_sync =
405
+ Arc :: new ( EsploraSyncClient :: new ( server_url. clone ( ) , Arc :: clone ( & logger) ) ) ;
406
+ let blockchain = EsploraBlockchain :: from_client (
407
+ tx_sync. client ( ) . clone ( ) ,
408
+ BDK_CLIENT_STOP_GAP ,
409
+ )
410
+ . with_concurrency ( BDK_CLIENT_CONCURRENCY ) ;
411
+ ( blockchain, tx_sync)
412
+ }
413
+ }
414
+ } else {
415
+ // Default to Esplora client with blockstream endpoint.
416
+ let server_url = DEFAULT_ESPLORA_SERVER_URL . to_string ( ) ;
417
+ let tx_sync = Arc :: new ( EsploraSyncClient :: new ( server_url, Arc :: clone ( & logger) ) ) ;
418
+ let blockchain =
419
+ EsploraBlockchain :: from_client ( tx_sync. client ( ) . clone ( ) , BDK_CLIENT_STOP_GAP )
420
+ . with_concurrency ( BDK_CLIENT_CONCURRENCY ) ;
421
+ ( blockchain, tx_sync)
422
+ } ;
387
423
388
424
let runtime = Arc :: new ( RwLock :: new ( None ) ) ;
389
425
let wallet = Arc :: new ( Wallet :: new (
0 commit comments