Skip to content

Commit 14465d0

Browse files
committed
feat: initial bitcoind sync client support
Adds: - Sync client configuration with RPC (default) and REST variants - Extend the ChainSource::Bitcoind configuration options - Preliminary implementation for BitcoindSyncClient in RPC mode
1 parent 387cc2d commit 14465d0

File tree

9 files changed

+179
-77
lines changed

9 files changed

+179
-77
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ lightning-net-tokio = { version = "0.1.0" }
3535
lightning-persister = { version = "0.1.0" }
3636
lightning-background-processor = { version = "0.1.0", features = ["futures"] }
3737
lightning-rapid-gossip-sync = { version = "0.1.0" }
38-
lightning-block-sync = { version = "0.1.0", features = ["rpc-client", "tokio"] }
38+
lightning-block-sync = { version = "0.1.0", features = ["rpc-client", "rest-client", "tokio"] }
3939
lightning-transaction-sync = { version = "0.1.0", features = ["esplora-async-https", "time", "electrum"] }
4040
lightning-liquidity = { version = "0.1.0", features = ["std"] }
4141

bindings/ldk_node.udl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ dictionary ElectrumSyncConfig {
3434
BackgroundSyncConfig? background_sync_config;
3535
};
3636

37+
[Enum]
38+
interface BitcoindSyncClientConfig {
39+
Rpc();
40+
Rest(string rest_host, u16 rest_port);
41+
};
42+
3743
dictionary LSPS2ServiceConfig {
3844
string? require_token;
3945
boolean advertise_service;
@@ -77,7 +83,7 @@ interface Builder {
7783
void set_entropy_bip39_mnemonic(Mnemonic mnemonic, string? passphrase);
7884
void set_chain_source_esplora(string server_url, EsploraSyncConfig? config);
7985
void set_chain_source_electrum(string server_url, ElectrumSyncConfig? config);
80-
void set_chain_source_bitcoind_rpc(string rpc_host, u16 rpc_port, string rpc_user, string rpc_password);
86+
void set_chain_source_bitcoind(string rpc_host, u16 rpc_port, string rpc_user, string rpc_password, BitcoindSyncClientConfig? sync_client_config);
8187
void set_gossip_source_p2p();
8288
void set_gossip_source_rgs(string rgs_server_url);
8389
void set_liquidity_source_lsps1(PublicKey node_id, SocketAddress address, string? token);

src/builder.rs

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
use crate::chain::{ChainSource, DEFAULT_ESPLORA_SERVER_URL};
99
use crate::config::{
10-
default_user_config, may_announce_channel, AnnounceError, Config, ElectrumSyncConfig,
11-
EsploraSyncConfig, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN,
10+
default_user_config, may_announce_channel, AnnounceError, BitcoindSyncClientConfig, Config,
11+
ElectrumSyncConfig, EsploraSyncConfig, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL,
12+
WALLET_KEYS_SEED_LEN,
1213
};
1314

1415
use crate::connection::ConnectionManager;
@@ -84,9 +85,21 @@ const LSPS_HARDENED_CHILD_INDEX: u32 = 577;
8485

8586
#[derive(Debug, Clone)]
8687
enum ChainDataSourceConfig {
87-
Esplora { server_url: String, sync_config: Option<EsploraSyncConfig> },
88-
Electrum { server_url: String, sync_config: Option<ElectrumSyncConfig> },
89-
BitcoindRpc { rpc_host: String, rpc_port: u16, rpc_user: String, rpc_password: String },
88+
Esplora {
89+
server_url: String,
90+
sync_config: Option<EsploraSyncConfig>,
91+
},
92+
Electrum {
93+
server_url: String,
94+
sync_config: Option<ElectrumSyncConfig>,
95+
},
96+
Bitcoind {
97+
rpc_host: String,
98+
rpc_port: u16,
99+
rpc_user: String,
100+
rpc_password: String,
101+
sync_client_config: BitcoindSyncClientConfig,
102+
},
90103
}
91104

92105
#[derive(Debug, Clone)]
@@ -299,13 +312,26 @@ impl NodeBuilder {
299312
self
300313
}
301314

302-
/// Configures the [`Node`] instance to source its chain data from the given Bitcoin Core RPC
315+
/// Configures the [`Node`] instance to synchronize its chain data from the given Bitcoin Core RPC
303316
/// endpoint.
304-
pub fn set_chain_source_bitcoind_rpc(
317+
///
318+
/// This method configures an RPC connection for essential operations, with options for
319+
/// synchronization via either RPC (default) or REST.
320+
///
321+
/// # Parameters:
322+
/// * `rpc_host`, `rpc_port`, `rpc_user`, `rpc_password` - Required parameters for the Bitcoin Core RPC connection
323+
/// * `sync_client_config` - Optional synchronization client configuration; defaults to using RPC for sync
324+
pub fn set_chain_source_bitcoind(
305325
&mut self, rpc_host: String, rpc_port: u16, rpc_user: String, rpc_password: String,
326+
sync_client_config: Option<BitcoindSyncClientConfig>,
306327
) -> &mut Self {
307-
self.chain_data_source_config =
308-
Some(ChainDataSourceConfig::BitcoindRpc { rpc_host, rpc_port, rpc_user, rpc_password });
328+
self.chain_data_source_config = Some(ChainDataSourceConfig::Bitcoind {
329+
rpc_host,
330+
rpc_port,
331+
rpc_user,
332+
rpc_password,
333+
sync_client_config: sync_client_config.unwrap_or(BitcoindSyncClientConfig::Rpc),
334+
});
309335
self
310336
}
311337

@@ -718,14 +744,16 @@ impl ArcedNodeBuilder {
718744

719745
/// Configures the [`Node`] instance to source its chain data from the given Bitcoin Core RPC
720746
/// endpoint.
721-
pub fn set_chain_source_bitcoind_rpc(
747+
pub fn set_chain_source_bitcoind(
722748
&self, rpc_host: String, rpc_port: u16, rpc_user: String, rpc_password: String,
749+
sync_client_config: Option<BitcoindSyncClientConfig>,
723750
) {
724-
self.inner.write().unwrap().set_chain_source_bitcoind_rpc(
751+
self.inner.write().unwrap().set_chain_source_bitcoind(
725752
rpc_host,
726753
rpc_port,
727754
rpc_user,
728755
rpc_password,
756+
sync_client_config,
729757
);
730758
}
731759

@@ -1068,21 +1096,26 @@ fn build_with_store_internal(
10681096
Arc::clone(&node_metrics),
10691097
))
10701098
},
1071-
Some(ChainDataSourceConfig::BitcoindRpc { rpc_host, rpc_port, rpc_user, rpc_password }) => {
1072-
Arc::new(ChainSource::new_bitcoind_rpc(
1073-
rpc_host.clone(),
1074-
*rpc_port,
1075-
rpc_user.clone(),
1076-
rpc_password.clone(),
1077-
Arc::clone(&wallet),
1078-
Arc::clone(&fee_estimator),
1079-
Arc::clone(&tx_broadcaster),
1080-
Arc::clone(&kv_store),
1081-
Arc::clone(&config),
1082-
Arc::clone(&logger),
1083-
Arc::clone(&node_metrics),
1084-
))
1085-
},
1099+
Some(ChainDataSourceConfig::Bitcoind {
1100+
rpc_host,
1101+
rpc_port,
1102+
rpc_user,
1103+
rpc_password,
1104+
sync_client_config,
1105+
}) => Arc::new(ChainSource::new_bitcoind(
1106+
rpc_host.clone(),
1107+
*rpc_port,
1108+
rpc_user.clone(),
1109+
rpc_password.clone(),
1110+
Arc::clone(&wallet),
1111+
Arc::clone(&fee_estimator),
1112+
Arc::clone(&tx_broadcaster),
1113+
Arc::clone(&kv_store),
1114+
Arc::clone(&config),
1115+
sync_client_config.clone(),
1116+
Arc::clone(&logger),
1117+
Arc::clone(&node_metrics),
1118+
)),
10861119
None => {
10871120
// Default to Esplora client.
10881121
let server_url = DEFAULT_ESPLORA_SERVER_URL.to_string();

src/chain/bitcoind_rpc.rs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use lightning_block_sync::http::HttpEndpoint;
1313
use lightning_block_sync::http::JsonResponse;
1414
use lightning_block_sync::poll::ValidatedBlockHeader;
1515
use lightning_block_sync::rpc::{RpcClient, RpcError};
16-
use lightning_block_sync::{
17-
AsyncBlockSourceResult, BlockData, BlockHeaderData, BlockSource, Cache,
18-
};
16+
use lightning_block_sync::Cache;
1917

2018
use serde::Serialize;
2119

@@ -36,9 +34,8 @@ pub struct BitcoindRpcClient {
3634

3735
impl BitcoindRpcClient {
3836
pub(crate) fn new(host: String, port: u16, rpc_user: String, rpc_password: String) -> Self {
39-
let http_endpoint = HttpEndpoint::for_host(host.clone()).with_port(port);
40-
let rpc_credentials =
41-
BASE64_STANDARD.encode(format!("{}:{}", rpc_user.clone(), rpc_password.clone()));
37+
let http_endpoint = endpoint(host, port);
38+
let rpc_credentials = rpc_credentials(rpc_user, rpc_password);
4239

4340
let rpc_client = Arc::new(RpcClient::new(&rpc_credentials, http_endpoint));
4441

@@ -254,22 +251,12 @@ impl BitcoindRpcClient {
254251
}
255252
}
256253

257-
impl BlockSource for BitcoindRpcClient {
258-
fn get_header<'a>(
259-
&'a self, header_hash: &'a BlockHash, height_hint: Option<u32>,
260-
) -> AsyncBlockSourceResult<'a, BlockHeaderData> {
261-
Box::pin(async move { self.rpc_client.get_header(header_hash, height_hint).await })
262-
}
263-
264-
fn get_block<'a>(
265-
&'a self, header_hash: &'a BlockHash,
266-
) -> AsyncBlockSourceResult<'a, BlockData> {
267-
Box::pin(async move { self.rpc_client.get_block(header_hash).await })
268-
}
254+
pub(crate) fn rpc_credentials(rpc_user: String, rpc_password: String) -> String {
255+
BASE64_STANDARD.encode(format!("{}:{}", rpc_user, rpc_password))
256+
}
269257

270-
fn get_best_block(&self) -> AsyncBlockSourceResult<(BlockHash, Option<u32>)> {
271-
Box::pin(async move { self.rpc_client.get_best_block().await })
272-
}
258+
pub(crate) fn endpoint(host: String, port: u16) -> HttpEndpoint {
259+
HttpEndpoint::for_host(host.clone()).with_port(port)
273260
}
274261

275262
pub(crate) struct FeeResponse(pub FeeRate);

0 commit comments

Comments
 (0)