init_regtest.rs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. use std::env;
  2. use std::path::{Path, PathBuf};
  3. use std::sync::Arc;
  4. use anyhow::Result;
  5. use cdk::types::FeeReserve;
  6. use cdk_cln::Cln as CdkCln;
  7. use cdk_lnd::Lnd as CdkLnd;
  8. use ln_regtest_rs::bitcoin_client::BitcoinClient;
  9. use ln_regtest_rs::bitcoind::Bitcoind;
  10. use ln_regtest_rs::cln::Clnd;
  11. use ln_regtest_rs::ln_client::{ClnClient, LightningClient, LndClient};
  12. use ln_regtest_rs::lnd::Lnd;
  13. use tokio::sync::oneshot::Sender;
  14. use tokio::sync::Notify;
  15. pub const BITCOIND_ADDR: &str = "127.0.0.1:18443";
  16. pub const ZMQ_RAW_BLOCK: &str = "tcp://127.0.0.1:28332";
  17. pub const ZMQ_RAW_TX: &str = "tcp://127.0.0.1:28333";
  18. pub const BITCOIN_RPC_USER: &str = "testuser";
  19. pub const BITCOIN_RPC_PASS: &str = "testpass";
  20. const BITCOIN_DIR: &str = "bitcoin";
  21. pub const LND_ADDR: &str = "0.0.0.0:18449";
  22. pub const LND_RPC_ADDR: &str = "localhost:10009";
  23. pub const LND_TWO_ADDR: &str = "0.0.0.0:18410";
  24. pub const LND_TWO_RPC_ADDR: &str = "localhost:10010";
  25. pub const CLN_ADDR: &str = "127.0.0.1:19846";
  26. pub const CLN_TWO_ADDR: &str = "127.0.0.1:19847";
  27. pub fn get_mint_addr() -> String {
  28. env::var("cdk_itests_mint_addr").expect("Temp dir set")
  29. }
  30. pub fn get_mint_port(which: &str) -> u16 {
  31. let dir = env::var(format!("cdk_itests_mint_port_{}", which)).expect("Temp dir set");
  32. dir.parse().unwrap()
  33. }
  34. pub fn get_mint_url(which: &str) -> String {
  35. format!("http://{}:{}", get_mint_addr(), get_mint_port(which))
  36. }
  37. pub fn get_mint_ws_url(which: &str) -> String {
  38. format!("ws://{}:{}/v1/ws", get_mint_addr(), get_mint_port(which))
  39. }
  40. pub fn get_temp_dir() -> PathBuf {
  41. let dir = env::var("cdk_itests").expect("Temp dir set");
  42. std::fs::create_dir_all(&dir).unwrap();
  43. dir.parse().expect("Valid path buf")
  44. }
  45. pub fn get_bitcoin_dir() -> PathBuf {
  46. let dir = get_temp_dir().join(BITCOIN_DIR);
  47. std::fs::create_dir_all(&dir).unwrap();
  48. dir
  49. }
  50. pub fn init_bitcoind() -> Bitcoind {
  51. Bitcoind::new(
  52. get_bitcoin_dir(),
  53. BITCOIND_ADDR.parse().unwrap(),
  54. BITCOIN_RPC_USER.to_string(),
  55. BITCOIN_RPC_PASS.to_string(),
  56. ZMQ_RAW_BLOCK.to_string(),
  57. ZMQ_RAW_TX.to_string(),
  58. )
  59. }
  60. pub fn init_bitcoin_client() -> Result<BitcoinClient> {
  61. BitcoinClient::new(
  62. "wallet".to_string(),
  63. BITCOIND_ADDR.into(),
  64. None,
  65. Some(BITCOIN_RPC_USER.to_string()),
  66. Some(BITCOIN_RPC_PASS.to_string()),
  67. )
  68. }
  69. pub fn get_cln_dir(name: &str) -> PathBuf {
  70. let dir = get_temp_dir().join("cln").join(name);
  71. std::fs::create_dir_all(&dir).unwrap();
  72. dir
  73. }
  74. pub fn get_lnd_dir(name: &str) -> PathBuf {
  75. let dir = get_temp_dir().join("lnd").join(name);
  76. std::fs::create_dir_all(&dir).unwrap();
  77. dir
  78. }
  79. pub fn get_lnd_cert_file_path(lnd_dir: &Path) -> PathBuf {
  80. lnd_dir.join("tls.cert")
  81. }
  82. pub fn get_lnd_macaroon_path(lnd_dir: &Path) -> PathBuf {
  83. lnd_dir.join("data/chain/bitcoin/regtest/admin.macaroon")
  84. }
  85. pub async fn init_lnd(lnd_dir: PathBuf, lnd_addr: &str, lnd_rpc_addr: &str) -> Lnd {
  86. Lnd::new(
  87. get_bitcoin_dir(),
  88. lnd_dir,
  89. lnd_addr.parse().unwrap(),
  90. lnd_rpc_addr.to_string(),
  91. BITCOIN_RPC_USER.to_string(),
  92. BITCOIN_RPC_PASS.to_string(),
  93. ZMQ_RAW_BLOCK.to_string(),
  94. ZMQ_RAW_TX.to_string(),
  95. )
  96. }
  97. pub fn generate_block(bitcoin_client: &BitcoinClient) -> Result<()> {
  98. let mine_to_address = bitcoin_client.get_new_address()?;
  99. bitcoin_client.generate_blocks(&mine_to_address, 10)?;
  100. Ok(())
  101. }
  102. pub async fn create_cln_backend(cln_client: &ClnClient) -> Result<CdkCln> {
  103. let rpc_path = cln_client.rpc_path.clone();
  104. let fee_reserve = FeeReserve {
  105. min_fee_reserve: 1.into(),
  106. percent_fee_reserve: 1.0,
  107. };
  108. Ok(CdkCln::new(rpc_path, fee_reserve).await?)
  109. }
  110. pub async fn create_lnd_backend(lnd_client: &LndClient) -> Result<CdkLnd> {
  111. let fee_reserve = FeeReserve {
  112. min_fee_reserve: 1.into(),
  113. percent_fee_reserve: 1.0,
  114. };
  115. Ok(CdkLnd::new(
  116. lnd_client.address.clone(),
  117. lnd_client.cert_file.clone(),
  118. lnd_client.macaroon_file.clone(),
  119. fee_reserve,
  120. )
  121. .await?)
  122. }
  123. pub async fn fund_ln<C>(bitcoin_client: &BitcoinClient, ln_client: &C) -> Result<()>
  124. where
  125. C: LightningClient,
  126. {
  127. let ln_address = ln_client.get_new_onchain_address().await?;
  128. bitcoin_client.send_to_address(&ln_address, 5_000_000)?;
  129. ln_client.wait_chain_sync().await?;
  130. let mine_to_address = bitcoin_client.get_new_address()?;
  131. bitcoin_client.generate_blocks(&mine_to_address, 10)?;
  132. ln_client.wait_chain_sync().await?;
  133. Ok(())
  134. }
  135. pub async fn open_channel<C1, C2>(cln_client: &C1, lnd_client: &C2) -> Result<()>
  136. where
  137. C1: LightningClient,
  138. C2: LightningClient,
  139. {
  140. let cln_info = cln_client.get_connect_info().await?;
  141. let cln_pubkey = cln_info.pubkey;
  142. let cln_address = cln_info.address;
  143. let cln_port = cln_info.port;
  144. lnd_client
  145. .connect_peer(cln_pubkey.to_string(), cln_address.to_string(), cln_port)
  146. .await
  147. .unwrap();
  148. cln_client.wait_chain_sync().await?;
  149. lnd_client.wait_chain_sync().await?;
  150. lnd_client
  151. .open_channel(1_500_000, &cln_pubkey.to_string(), Some(750_000))
  152. .await
  153. .unwrap();
  154. Ok(())
  155. }
  156. pub async fn start_regtest_end(sender: Sender<()>, notify: Arc<Notify>) -> anyhow::Result<()> {
  157. let mut bitcoind = init_bitcoind();
  158. bitcoind.start_bitcoind()?;
  159. let bitcoin_client = init_bitcoin_client()?;
  160. bitcoin_client.create_wallet().ok();
  161. bitcoin_client.load_wallet()?;
  162. let new_add = bitcoin_client.get_new_address()?;
  163. bitcoin_client.generate_blocks(&new_add, 200).unwrap();
  164. let cln_one_dir = get_cln_dir("one");
  165. let mut clnd = Clnd::new(
  166. get_bitcoin_dir(),
  167. cln_one_dir.clone(),
  168. CLN_ADDR.into(),
  169. BITCOIN_RPC_USER.to_string(),
  170. BITCOIN_RPC_PASS.to_string(),
  171. );
  172. clnd.start_clnd()?;
  173. let cln_client = ClnClient::new(cln_one_dir.clone(), None).await?;
  174. cln_client.wait_chain_sync().await.unwrap();
  175. fund_ln(&bitcoin_client, &cln_client).await.unwrap();
  176. // Create second cln
  177. let cln_two_dir = get_cln_dir("two");
  178. let mut clnd_two = Clnd::new(
  179. get_bitcoin_dir(),
  180. cln_two_dir.clone(),
  181. CLN_TWO_ADDR.into(),
  182. BITCOIN_RPC_USER.to_string(),
  183. BITCOIN_RPC_PASS.to_string(),
  184. );
  185. clnd_two.start_clnd()?;
  186. let cln_two_client = ClnClient::new(cln_two_dir.clone(), None).await?;
  187. cln_two_client.wait_chain_sync().await.unwrap();
  188. fund_ln(&bitcoin_client, &cln_two_client).await.unwrap();
  189. let lnd_dir = get_lnd_dir("one");
  190. println!("{}", lnd_dir.display());
  191. let mut lnd = init_lnd(lnd_dir.clone(), LND_ADDR, LND_RPC_ADDR).await;
  192. lnd.start_lnd().unwrap();
  193. tracing::info!("Started lnd node");
  194. let lnd_client = LndClient::new(
  195. format!("https://{}", LND_RPC_ADDR),
  196. get_lnd_cert_file_path(&lnd_dir),
  197. get_lnd_macaroon_path(&lnd_dir),
  198. )
  199. .await?;
  200. lnd_client.wait_chain_sync().await.unwrap();
  201. fund_ln(&bitcoin_client, &lnd_client).await.unwrap();
  202. // create second lnd node
  203. let lnd_two_dir = get_lnd_dir("two");
  204. let mut lnd_two = init_lnd(lnd_two_dir.clone(), LND_TWO_ADDR, LND_TWO_RPC_ADDR).await;
  205. lnd_two.start_lnd().unwrap();
  206. tracing::info!("Started second lnd node");
  207. let lnd_two_client = LndClient::new(
  208. format!("https://{}", LND_TWO_RPC_ADDR),
  209. get_lnd_cert_file_path(&lnd_two_dir),
  210. get_lnd_macaroon_path(&lnd_two_dir),
  211. )
  212. .await?;
  213. lnd_two_client.wait_chain_sync().await.unwrap();
  214. fund_ln(&bitcoin_client, &lnd_two_client).await.unwrap();
  215. // Open channels concurrently
  216. // Open channels
  217. {
  218. open_channel(&cln_client, &lnd_client).await.unwrap();
  219. tracing::info!("Opened channel between cln and lnd one");
  220. generate_block(&bitcoin_client)?;
  221. // open_channel(&bitcoin_client, &cln_client, &cln_two_client)
  222. // .await
  223. // .unwrap();
  224. // tracing::info!("Opened channel between cln and cln two");
  225. open_channel(&lnd_client, &lnd_two_client).await.unwrap();
  226. tracing::info!("Opened channel between lnd and lnd two");
  227. generate_block(&bitcoin_client)?;
  228. // open_channel(&cln_client, &lnd_two_client).await.unwrap();
  229. // tracing::info!("Opened channel between cln and lnd two");
  230. open_channel(&cln_two_client, &lnd_client).await.unwrap();
  231. tracing::info!("Opened channel between cln two and lnd");
  232. generate_block(&bitcoin_client)?;
  233. open_channel(&cln_client, &lnd_two_client).await.unwrap();
  234. tracing::info!("Opened channel between cln and lnd two");
  235. generate_block(&bitcoin_client)?;
  236. cln_client.wait_channels_active().await?;
  237. cln_two_client.wait_channels_active().await?;
  238. lnd_client.wait_channels_active().await?;
  239. lnd_two_client.wait_channels_active().await?;
  240. }
  241. // Send notification that regtest set up is complete
  242. sender.send(()).expect("Could not send oneshot");
  243. // Wait until we are told to shutdown
  244. // If we return the bitcoind, lnd, and cln will be dropped and shutdown
  245. notify.notified().await;
  246. Ok(())
  247. }