Skip to content

Commit 070314f

Browse files
committed
Move esplora config to ChainDataSourceConfig
After we already have `EntropySourceConfig` and `GossipSourceConfig`, we here move the esplora server URL to a corresponding `enum ChainDataSourceConfig`, which will us to add further variants (e.g., `Electrum`) in the future without breaking the API. Additionally, we document the set defaults and switch our default config to `Network::Bitcoin` while we're here.
1 parent 46af7c5 commit 070314f

File tree

4 files changed

+98
-56
lines changed

4 files changed

+98
-56
lines changed

bindings/ldk_node.udl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ namespace ldk_node {
33

44
dictionary Config {
55
string storage_dir_path;
6-
string esplora_server_url;
76
Network network;
87
SocketAddr? listening_address;
98
u32 default_cltv_expiry_delta;
@@ -16,10 +15,10 @@ interface Builder {
1615
void set_entropy_seed_path(string seed_path);
1716
void set_entropy_seed_bytes(sequence<u8> seed_bytes);
1817
void set_entropy_bip39_mnemonic(Mnemonic mnemonic, string? passphrase);
18+
void set_esplora_server(string esplora_server_url);
1919
void set_gossip_source_p2p();
2020
void set_gossip_source_rgs(string rgs_server_url);
2121
void set_storage_dir_path(string storage_dir_path);
22-
void set_esplora_server_url(string esplora_server_url);
2322
void set_network(Network network);
2423
void set_listening_address(SocketAddr listening_address);
2524
Node build();

src/lib.rs

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
//! fn main() {
3636
//! let mut builder = Builder::new();
3737
//! 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());
3939
//!
4040
//! let node = builder.build();
4141
//! node.start().unwrap();
@@ -177,11 +177,19 @@ const WALLET_KEYS_SEED_LEN: usize = 64;
177177

178178
#[derive(Debug, Clone)]
179179
/// Represents the configuration of an [`Node`] instance.
180+
///
181+
/// ### Defaults
182+
///
183+
/// | Parameter | Value |
184+
/// |-----------------------------|------------------|
185+
/// | `storage_dir_path` | /tmp/ldk_node/ |
186+
/// | `network` | Network::Bitcoin |
187+
/// | `listening_address` | 0.0.0.0:9735 |
188+
/// | `default_cltv_expiry_delta` | 144 |
189+
///
180190
pub struct Config {
181191
/// The path where the underlying LDK and BDK persist their data.
182192
pub storage_dir_path: String,
183-
/// The URL of the utilized Esplora server.
184-
pub esplora_server_url: String,
185193
/// The used Bitcoin network.
186194
pub network: Network,
187195
/// The IP address and TCP port the node will listen on.
@@ -194,14 +202,18 @@ impl Default for Config {
194202
fn default() -> Self {
195203
Self {
196204
storage_dir_path: "/tmp/ldk_node/".to_string(),
197-
esplora_server_url: "http://localhost:3002".to_string(),
198-
network: Network::Regtest,
205+
network: Network::Bitcoin,
199206
listening_address: Some("0.0.0.0:9735".parse().unwrap()),
200207
default_cltv_expiry_delta: 144,
201208
}
202209
}
203210
}
204211

212+
#[derive(Debug, Clone)]
213+
enum ChainDataSourceConfig {
214+
Esplora(String),
215+
}
216+
205217
#[derive(Debug, Clone)]
206218
enum EntropySourceConfig {
207219
SeedFile(String),
@@ -217,9 +229,15 @@ enum GossipSourceConfig {
217229

218230
/// A builder for an [`Node`] instance, allowing to set some configuration and module choices from
219231
/// the getgo.
232+
///
233+
/// ### Defaults
234+
/// - Chain data is sourced from the Esplora endpoint `https://blockstream.info/api`
235+
/// - Wallet entropy is sourced from a `keys_seed` file located under [`Config::storage_dir_path`]
236+
/// - Gossip data is sourced via the peer-to-peer network
220237
#[derive(Debug)]
221238
pub struct Builder {
222239
config: Mutex<Config>,
240+
chain_data_source_config: Mutex<Option<ChainDataSourceConfig>>,
223241
entropy_source_config: Mutex<Option<EntropySourceConfig>>,
224242
gossip_source_config: Mutex<Option<GossipSourceConfig>>,
225243
}
@@ -228,17 +246,19 @@ impl Builder {
228246
/// Creates a new builder instance with the default configuration.
229247
pub fn new() -> Self {
230248
let config = Mutex::new(Config::default());
249+
let chain_data_source_config = Mutex::new(None);
231250
let entropy_source_config = Mutex::new(None);
232251
let gossip_source_config = Mutex::new(None);
233-
Self { config, entropy_source_config, gossip_source_config }
252+
Self { config, chain_data_source_config, entropy_source_config, gossip_source_config }
234253
}
235254

236255
/// Creates a new builder instance from an [`Config`].
237256
pub fn from_config(config: Config) -> Self {
238257
let config = Mutex::new(config);
258+
let chain_data_source_config = Mutex::new(None);
239259
let entropy_source_config = Mutex::new(None);
240260
let gossip_source_config = Mutex::new(None);
241-
Self { config, entropy_source_config, gossip_source_config }
261+
Self { config, chain_data_source_config, entropy_source_config, gossip_source_config }
242262
}
243263

244264
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
@@ -270,6 +290,12 @@ impl Builder {
270290
Some(EntropySourceConfig::Bip39Mnemonic { mnemonic, passphrase });
271291
}
272292

293+
/// Configures the [`Node`] instance to source its chain data from the given Esplora server.
294+
pub fn set_esplora_server(&self, esplora_server_url: String) {
295+
*self.chain_data_source_config.lock().unwrap() =
296+
Some(ChainDataSourceConfig::Esplora(esplora_server_url));
297+
}
298+
273299
/// Configures the [`Node`] instance to source its gossip data from the Lightning peer-to-peer
274300
/// network.
275301
pub fn set_gossip_source_p2p(&self) {
@@ -284,30 +310,18 @@ impl Builder {
284310
}
285311

286312
/// Sets the used storage directory path.
287-
///
288-
/// Default: `/tmp/ldk_node/`
289313
pub fn set_storage_dir_path(&self, storage_dir_path: String) {
290314
let mut config = self.config.lock().unwrap();
291315
config.storage_dir_path = storage_dir_path;
292316
}
293317

294-
/// Sets the Esplora server URL.
295-
///
296-
/// Default: `https://blockstream.info/api`
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;
300-
}
301-
302318
/// Sets the Bitcoin network used.
303319
pub fn set_network(&self, network: Network) {
304320
let mut config = self.config.lock().unwrap();
305321
config.network = network;
306322
}
307323

308324
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
309-
///
310-
/// Default: `0.0.0.0:9735`
311325
pub fn set_listening_address(&self, listening_address: SocketAddr) {
312326
let mut config = self.config.lock().unwrap();
313327
config.listening_address = Some(listening_address);
@@ -370,14 +384,30 @@ impl Builder {
370384
)
371385
.expect("Failed to set up on-chain wallet");
372386

373-
let tx_sync = Arc::new(EsploraSyncClient::new(
374-
config.esplora_server_url.clone(),
375-
Arc::clone(&logger),
376-
));
377-
378-
let blockchain =
379-
EsploraBlockchain::from_client(tx_sync.client().clone(), BDK_CLIENT_STOP_GAP)
380-
.with_concurrency(BDK_CLIENT_CONCURRENCY);
387+
let (blockchain, tx_sync) = if let Some(chain_data_source_config) =
388+
&*self.chain_data_source_config.lock().unwrap()
389+
{
390+
match chain_data_source_config {
391+
ChainDataSourceConfig::Esplora(server_url) => {
392+
let tx_sync =
393+
Arc::new(EsploraSyncClient::new(server_url.clone(), Arc::clone(&logger)));
394+
let blockchain = EsploraBlockchain::from_client(
395+
tx_sync.client().clone(),
396+
BDK_CLIENT_STOP_GAP,
397+
)
398+
.with_concurrency(BDK_CLIENT_CONCURRENCY);
399+
(blockchain, tx_sync)
400+
}
401+
}
402+
} else {
403+
// Default to Esplora client with blockstream endpoint.
404+
let server_url = "https://blockstream.info/api".to_string();
405+
let tx_sync = Arc::new(EsploraSyncClient::new(server_url, Arc::clone(&logger)));
406+
let blockchain =
407+
EsploraBlockchain::from_client(tx_sync.client().clone(), BDK_CLIENT_STOP_GAP)
408+
.with_concurrency(BDK_CLIENT_CONCURRENCY);
409+
(blockchain, tx_sync)
410+
};
381411

382412
let runtime = Arc::new(RwLock::new(None));
383413
let wallet = Arc::new(Wallet::new(

src/test/functional_tests.rs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ use bitcoin::Amount;
88
fn channel_full_cycle() {
99
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
1010
println!("== Node A ==");
11-
let esplora_url = electrsd.esplora_url.as_ref().unwrap();
12-
let config_a = random_config(esplora_url);
13-
let node_a = Builder::from_config(config_a).build();
11+
let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap());
12+
let config_a = random_config();
13+
let builder_a = Builder::from_config(config_a);
14+
builder_a.set_esplora_server(esplora_url.clone());
15+
let node_a = builder_a.build();
1416
node_a.start().unwrap();
1517
let addr_a = node_a.new_funding_address().unwrap();
1618

1719
println!("\n== Node B ==");
18-
let config_b = random_config(esplora_url);
19-
let node_b = Builder::from_config(config_b).build();
20+
let config_b = random_config();
21+
let builder_b = Builder::from_config(config_b);
22+
builder_b.set_esplora_server(esplora_url);
23+
let node_b = builder_b.build();
2024
node_b.start().unwrap();
2125
let addr_b = node_b.new_funding_address().unwrap();
2226

@@ -212,15 +216,19 @@ fn channel_full_cycle() {
212216
fn channel_open_fails_when_funds_insufficient() {
213217
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
214218
println!("== Node A ==");
215-
let esplora_url = electrsd.esplora_url.as_ref().unwrap();
216-
let config_a = random_config(&esplora_url);
217-
let node_a = Builder::from_config(config_a).build();
219+
let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap());
220+
let config_a = random_config();
221+
let builder_a = Builder::from_config(config_a);
222+
builder_a.set_esplora_server(esplora_url.clone());
223+
let node_a = builder_a.build();
218224
node_a.start().unwrap();
219225
let addr_a = node_a.new_funding_address().unwrap();
220226

221227
println!("\n== Node B ==");
222-
let config_b = random_config(&esplora_url);
223-
let node_b = Builder::from_config(config_b).build();
228+
let config_b = random_config();
229+
let builder_b = Builder::from_config(config_b);
230+
builder_b.set_esplora_server(esplora_url);
231+
let node_b = builder_b.build();
224232
node_b.start().unwrap();
225233
let addr_b = node_b.new_funding_address().unwrap();
226234

@@ -252,12 +260,11 @@ fn channel_open_fails_when_funds_insufficient() {
252260

253261
#[test]
254262
fn connect_to_public_testnet_esplora() {
255-
let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd();
256-
let esplora_url = electrsd.esplora_url.as_ref().unwrap();
257-
let mut config = random_config(&esplora_url);
258-
config.esplora_server_url = "https://blockstream.info/testnet/api".to_string();
263+
let mut config = random_config();
259264
config.network = bitcoin::Network::Testnet;
260-
let node = Builder::from_config(config).build();
265+
let builder = Builder::from_config(config);
266+
builder.set_esplora_server("https://blockstream.info/testnet/api".to_string());
267+
let node = builder.build();
261268
node.start().unwrap();
262269
node.sync_wallets().unwrap();
263270
node.stop().unwrap();
@@ -266,9 +273,11 @@ fn connect_to_public_testnet_esplora() {
266273
#[test]
267274
fn start_stop_reinit() {
268275
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
269-
let esplora_url = electrsd.esplora_url.as_ref().unwrap();
270-
let config = random_config(&esplora_url);
271-
let node = Builder::from_config(config.clone()).build();
276+
let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap());
277+
let config = random_config();
278+
let builder = Builder::from_config(config.clone());
279+
builder.set_esplora_server(esplora_url);
280+
let node = builder.build();
272281
let expected_node_id = node.node_id();
273282

274283
let funding_address = node.new_funding_address().unwrap();
@@ -315,15 +324,19 @@ fn start_stop_reinit() {
315324
#[test]
316325
fn onchain_spend_receive() {
317326
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
318-
let esplora_url = electrsd.esplora_url.as_ref().unwrap();
327+
let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap());
319328

320-
let config_a = random_config(esplora_url);
321-
let node_a = Builder::from_config(config_a).build();
329+
let config_a = random_config();
330+
let builder_a = Builder::from_config(config_a);
331+
builder_a.set_esplora_server(esplora_url.clone());
332+
let node_a = builder_a.build();
322333
node_a.start().unwrap();
323334
let addr_a = node_a.new_funding_address().unwrap();
324335

325-
let config_b = random_config(esplora_url);
326-
let node_b = Builder::from_config(config_b).build();
336+
let config_b = random_config();
337+
let builder_b = Builder::from_config(config_b);
338+
builder_b.set_esplora_server(esplora_url);
339+
let node_b = builder_b.build();
327340
node_b.start().unwrap();
328341
let addr_b = node_b.new_funding_address().unwrap();
329342

src/test/utils.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use lightning::util::logger::{Level, Logger, Record};
44
use lightning::util::persist::KVStorePersister;
55
use lightning::util::ser::Writeable;
66

7-
use bitcoin::{Address, Amount, OutPoint, Txid};
7+
use bitcoin::{Address, Amount, Network, OutPoint, Txid};
88

99
use bitcoind::bitcoincore_rpc::RpcApi;
1010
use electrsd::bitcoind::bitcoincore_rpc::bitcoincore_rpc_json::AddressType;
@@ -282,11 +282,11 @@ pub fn random_port() -> u16 {
282282
rng.gen_range(5000..65535)
283283
}
284284

285-
pub fn random_config(esplora_url: &str) -> Config {
285+
pub fn random_config() -> Config {
286286
let mut config = Config::default();
287287

288-
println!("Setting esplora server URL: {}", esplora_url);
289-
config.esplora_server_url = format!("http://{}", esplora_url);
288+
config.network = Network::Regtest;
289+
println!("Setting network: {}", config.network);
290290

291291
let rand_dir = random_storage_path();
292292
println!("Setting random LDK storage dir: {}", rand_dir);

0 commit comments

Comments
 (0)