1+ use crate :: test:: utils:: * ;
12use crate :: test:: utils:: { expect_event, random_config} ;
23use crate :: { Builder , Error , Event , PaymentDirection , PaymentStatus } ;
34
4- use bitcoin:: { Address , Amount , OutPoint , Txid } ;
5- use bitcoind:: bitcoincore_rpc:: RpcApi ;
6- use electrsd:: bitcoind:: bitcoincore_rpc:: bitcoincore_rpc_json:: AddressType ;
7- use electrsd:: { bitcoind, bitcoind:: BitcoinD , ElectrsD } ;
8- use electrum_client:: ElectrumApi ;
5+ use bitcoin:: Amount ;
96
10- use once_cell:: sync:: OnceCell ;
11-
12- use std:: env;
13- use std:: sync:: Mutex ;
147use std:: time:: Duration ;
15-
16- static BITCOIND : OnceCell < BitcoinD > = OnceCell :: new ( ) ;
17- static ELECTRSD : OnceCell < ElectrsD > = OnceCell :: new ( ) ;
18- static PREMINE : OnceCell < ( ) > = OnceCell :: new ( ) ;
19- static MINER_LOCK : Mutex < ( ) > = Mutex :: new ( ( ) ) ;
20-
21- fn get_bitcoind ( ) -> & ' static BitcoinD {
22- BITCOIND . get_or_init ( || {
23- let bitcoind_exe =
24- env:: var ( "BITCOIND_EXE" ) . ok ( ) . or_else ( || bitcoind:: downloaded_exe_path ( ) . ok ( ) ) . expect (
25- "you need to provide an env var BITCOIND_EXE or specify a bitcoind version feature" ,
26- ) ;
27- let mut conf = bitcoind:: Conf :: default ( ) ;
28- conf. network = "regtest" ;
29- BitcoinD :: with_conf ( bitcoind_exe, & conf) . unwrap ( )
30- } )
31- }
32-
33- fn get_electrsd ( ) -> & ' static ElectrsD {
34- ELECTRSD . get_or_init ( || {
35- let bitcoind = get_bitcoind ( ) ;
36- let electrs_exe =
37- env:: var ( "ELECTRS_EXE" ) . ok ( ) . or_else ( electrsd:: downloaded_exe_path) . expect (
38- "you need to provide env var ELECTRS_EXE or specify an electrsd version feature" ,
39- ) ;
40- let mut conf = electrsd:: Conf :: default ( ) ;
41- conf. http_enabled = true ;
42- conf. network = "regtest" ;
43- ElectrsD :: with_conf ( electrs_exe, & bitcoind, & conf) . unwrap ( )
44- } )
45- }
46-
47- fn generate_blocks_and_wait ( num : usize ) {
48- let _miner = MINER_LOCK . lock ( ) . unwrap ( ) ;
49- let cur_height = get_bitcoind ( ) . client . get_block_count ( ) . unwrap ( ) ;
50- let address =
51- get_bitcoind ( ) . client . get_new_address ( Some ( "test" ) , Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
52- let _block_hashes = get_bitcoind ( ) . client . generate_to_address ( num as u64 , & address) . unwrap ( ) ;
53- wait_for_block ( cur_height as usize + num) ;
54- }
55-
56- fn wait_for_block ( min_height : usize ) {
57- let mut header = get_electrsd ( ) . client . block_headers_subscribe ( ) . unwrap ( ) ;
58- loop {
59- if header. height >= min_height {
60- break ;
61- }
62- header = exponential_backoff_poll ( || {
63- get_electrsd ( ) . trigger ( ) . unwrap ( ) ;
64- get_electrsd ( ) . client . ping ( ) . unwrap ( ) ;
65- get_electrsd ( ) . client . block_headers_pop ( ) . unwrap ( )
66- } ) ;
67- }
68- }
69-
70- fn wait_for_tx ( txid : Txid ) {
71- let mut tx_res = get_electrsd ( ) . client . transaction_get ( & txid) ;
72- loop {
73- if tx_res. is_ok ( ) {
74- break ;
75- }
76- tx_res = exponential_backoff_poll ( || {
77- get_electrsd ( ) . trigger ( ) . unwrap ( ) ;
78- get_electrsd ( ) . client . ping ( ) . unwrap ( ) ;
79- Some ( get_electrsd ( ) . client . transaction_get ( & txid) )
80- } ) ;
81- }
82- }
83-
84- fn wait_for_outpoint_spend ( outpoint : OutPoint ) {
85- let tx = get_electrsd ( ) . client . transaction_get ( & outpoint. txid ) . unwrap ( ) ;
86- let txout_script = tx. output . get ( outpoint. vout as usize ) . unwrap ( ) . clone ( ) . script_pubkey ;
87- let mut is_spent = !get_electrsd ( ) . client . script_get_history ( & txout_script) . unwrap ( ) . is_empty ( ) ;
88- loop {
89- if is_spent {
90- break ;
91- }
92-
93- is_spent = exponential_backoff_poll ( || {
94- get_electrsd ( ) . trigger ( ) . unwrap ( ) ;
95- get_electrsd ( ) . client . ping ( ) . unwrap ( ) ;
96- Some ( !get_electrsd ( ) . client . script_get_history ( & txout_script) . unwrap ( ) . is_empty ( ) )
97- } ) ;
98- }
99- }
100-
101- fn exponential_backoff_poll < T , F > ( mut poll : F ) -> T
102- where
103- F : FnMut ( ) -> Option < T > ,
104- {
105- let mut delay = Duration :: from_millis ( 64 ) ;
106- let mut tries = 0 ;
107- loop {
108- match poll ( ) {
109- Some ( data) => break data,
110- None if delay. as_millis ( ) < 512 => {
111- delay = delay. mul_f32 ( 2.0 ) ;
112- }
113-
114- None => { }
115- }
116- assert ! ( tries < 10 , "Reached max tries." ) ;
117- tries += 1 ;
118- std:: thread:: sleep ( delay) ;
119- }
120- }
121-
122- fn premine_and_distribute_funds ( addrs : Vec < Address > , amount : Amount ) {
123- PREMINE . get_or_init ( || {
124- generate_blocks_and_wait ( 101 ) ;
125- } ) ;
126-
127- for addr in addrs {
128- let txid = get_bitcoind ( )
129- . client
130- . send_to_address ( & addr, amount, None , None , None , None , None , None )
131- . unwrap ( ) ;
132- wait_for_tx ( txid) ;
133- }
134-
135- generate_blocks_and_wait ( 1 ) ;
136- }
137-
1388#[ test]
1399fn channel_full_cycle ( ) {
10+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
14011 println ! ( "== Node A ==" ) ;
141- let esplora_url = get_electrsd ( ) . esplora_url . as_ref ( ) . unwrap ( ) ;
12+ let esplora_url = electrsd . esplora_url . as_ref ( ) . unwrap ( ) ;
14213 let config_a = random_config ( esplora_url) ;
14314 let node_a = Builder :: from_config ( config_a) . build ( ) ;
14415 node_a. start ( ) . unwrap ( ) ;
@@ -150,7 +21,12 @@ fn channel_full_cycle() {
15021 node_b. start ( ) . unwrap ( ) ;
15122 let addr_b = node_b. new_funding_address ( ) . unwrap ( ) ;
15223
153- premine_and_distribute_funds ( vec ! [ addr_a, addr_b] , Amount :: from_sat ( 100000 ) ) ;
24+ premine_and_distribute_funds (
25+ & bitcoind,
26+ & electrsd,
27+ vec ! [ addr_a, addr_b] ,
28+ Amount :: from_sat ( 100000 ) ,
29+ ) ;
15430 node_a. sync_wallets ( ) . unwrap ( ) ;
15531 node_b. sync_wallets ( ) . unwrap ( ) ;
15632 assert_eq ! ( node_a. on_chain_balance( ) . unwrap( ) . get_spendable( ) , 100000 ) ;
@@ -170,10 +46,10 @@ fn channel_full_cycle() {
17046 }
17147 } ;
17248
173- wait_for_tx ( funding_txo. txid ) ;
49+ wait_for_tx ( & electrsd , funding_txo. txid ) ;
17450
17551 println ! ( "\n .. generating blocks, syncing wallets .. " ) ;
176- generate_blocks_and_wait ( 6 ) ;
52+ generate_blocks_and_wait ( & bitcoind , & electrsd , 6 ) ;
17753 node_a. sync_wallets ( ) . unwrap ( ) ;
17854 node_b. sync_wallets ( ) . unwrap ( ) ;
17955
@@ -276,9 +152,9 @@ fn channel_full_cycle() {
276152 expect_event ! ( node_a, ChannelClosed ) ;
277153 expect_event ! ( node_b, ChannelClosed ) ;
278154
279- wait_for_outpoint_spend ( funding_txo. into_bitcoin_outpoint ( ) ) ;
155+ wait_for_outpoint_spend ( & electrsd , funding_txo. into_bitcoin_outpoint ( ) ) ;
280156
281- generate_blocks_and_wait ( 1 ) ;
157+ generate_blocks_and_wait ( & bitcoind , & electrsd , 1 ) ;
282158 node_a. sync_wallets ( ) . unwrap ( ) ;
283159 node_b. sync_wallets ( ) . unwrap ( ) ;
284160
@@ -293,8 +169,9 @@ fn channel_full_cycle() {
293169
294170#[ test]
295171fn channel_open_fails_when_funds_insufficient ( ) {
172+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
296173 println ! ( "== Node A ==" ) ;
297- let esplora_url = get_electrsd ( ) . esplora_url . as_ref ( ) . unwrap ( ) ;
174+ let esplora_url = electrsd . esplora_url . as_ref ( ) . unwrap ( ) ;
298175 let config_a = random_config ( & esplora_url) ;
299176 let node_a = Builder :: from_config ( config_a) . build ( ) ;
300177 node_a. start ( ) . unwrap ( ) ;
@@ -306,7 +183,12 @@ fn channel_open_fails_when_funds_insufficient() {
306183 node_b. start ( ) . unwrap ( ) ;
307184 let addr_b = node_b. new_funding_address ( ) . unwrap ( ) ;
308185
309- premine_and_distribute_funds ( vec ! [ addr_a, addr_b] , Amount :: from_sat ( 100000 ) ) ;
186+ premine_and_distribute_funds (
187+ & bitcoind,
188+ & electrsd,
189+ vec ! [ addr_a, addr_b] ,
190+ Amount :: from_sat ( 100000 ) ,
191+ ) ;
310192 node_a. sync_wallets ( ) . unwrap ( ) ;
311193 node_b. sync_wallets ( ) . unwrap ( ) ;
312194 assert_eq ! ( node_a. on_chain_balance( ) . unwrap( ) . get_spendable( ) , 100000 ) ;
@@ -322,7 +204,8 @@ fn channel_open_fails_when_funds_insufficient() {
322204
323205#[ test]
324206fn connect_to_public_testnet_esplora ( ) {
325- let esplora_url = get_electrsd ( ) . esplora_url . as_ref ( ) . unwrap ( ) ;
207+ let ( _bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
208+ let esplora_url = electrsd. esplora_url . as_ref ( ) . unwrap ( ) ;
326209 let mut config = random_config ( & esplora_url) ;
327210 config. esplora_server_url = "https://blockstream.info/testnet/api" . to_string ( ) ;
328211 config. network = bitcoin:: Network :: Testnet ;
@@ -334,15 +217,16 @@ fn connect_to_public_testnet_esplora() {
334217
335218#[ test]
336219fn start_stop_reinit ( ) {
337- let esplora_url = get_electrsd ( ) . esplora_url . as_ref ( ) . unwrap ( ) ;
220+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
221+ let esplora_url = electrsd. esplora_url . as_ref ( ) . unwrap ( ) ;
338222 let config = random_config ( & esplora_url) ;
339223 let node = Builder :: from_config ( config. clone ( ) ) . build ( ) ;
340224 let expected_node_id = node. node_id ( ) ;
341225
342226 let funding_address = node. new_funding_address ( ) . unwrap ( ) ;
343227 let expected_amount = Amount :: from_sat ( 100000 ) ;
344228
345- premine_and_distribute_funds ( vec ! [ funding_address] , expected_amount) ;
229+ premine_and_distribute_funds ( & bitcoind , & electrsd , vec ! [ funding_address] , expected_amount) ;
346230 assert_eq ! ( node. on_chain_balance( ) . unwrap( ) . get_total( ) , 0 ) ;
347231
348232 node. start ( ) . unwrap ( ) ;
0 commit comments