1
+ use crate :: test:: utils:: * ;
1
2
use crate :: test:: utils:: { expect_event, random_config} ;
2
3
use crate :: { Builder , Error , Event , PaymentDirection , PaymentStatus } ;
3
4
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 ;
9
6
10
- use once_cell:: sync:: OnceCell ;
11
-
12
- use std:: env;
13
- use std:: sync:: Mutex ;
14
7
use 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
-
138
8
#[ test]
139
9
fn channel_full_cycle ( ) {
10
+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
140
11
println ! ( "== Node A ==" ) ;
141
- let esplora_url = get_electrsd ( ) . esplora_url . as_ref ( ) . unwrap ( ) ;
12
+ let esplora_url = electrsd . esplora_url . as_ref ( ) . unwrap ( ) ;
142
13
let config_a = random_config ( esplora_url) ;
143
14
let node_a = Builder :: from_config ( config_a) . build ( ) ;
144
15
node_a. start ( ) . unwrap ( ) ;
@@ -150,7 +21,12 @@ fn channel_full_cycle() {
150
21
node_b. start ( ) . unwrap ( ) ;
151
22
let addr_b = node_b. new_funding_address ( ) . unwrap ( ) ;
152
23
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
+ ) ;
154
30
node_a. sync_wallets ( ) . unwrap ( ) ;
155
31
node_b. sync_wallets ( ) . unwrap ( ) ;
156
32
assert_eq ! ( node_a. on_chain_balance( ) . unwrap( ) . get_spendable( ) , 100000 ) ;
@@ -170,10 +46,10 @@ fn channel_full_cycle() {
170
46
}
171
47
} ;
172
48
173
- wait_for_tx ( funding_txo. txid ) ;
49
+ wait_for_tx ( & electrsd , funding_txo. txid ) ;
174
50
175
51
println ! ( "\n .. generating blocks, syncing wallets .. " ) ;
176
- generate_blocks_and_wait ( 6 ) ;
52
+ generate_blocks_and_wait ( & bitcoind , & electrsd , 6 ) ;
177
53
node_a. sync_wallets ( ) . unwrap ( ) ;
178
54
node_b. sync_wallets ( ) . unwrap ( ) ;
179
55
@@ -276,9 +152,9 @@ fn channel_full_cycle() {
276
152
expect_event ! ( node_a, ChannelClosed ) ;
277
153
expect_event ! ( node_b, ChannelClosed ) ;
278
154
279
- wait_for_outpoint_spend ( funding_txo. into_bitcoin_outpoint ( ) ) ;
155
+ wait_for_outpoint_spend ( & electrsd , funding_txo. into_bitcoin_outpoint ( ) ) ;
280
156
281
- generate_blocks_and_wait ( 1 ) ;
157
+ generate_blocks_and_wait ( & bitcoind , & electrsd , 1 ) ;
282
158
node_a. sync_wallets ( ) . unwrap ( ) ;
283
159
node_b. sync_wallets ( ) . unwrap ( ) ;
284
160
@@ -293,8 +169,9 @@ fn channel_full_cycle() {
293
169
294
170
#[ test]
295
171
fn channel_open_fails_when_funds_insufficient ( ) {
172
+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
296
173
println ! ( "== Node A ==" ) ;
297
- let esplora_url = get_electrsd ( ) . esplora_url . as_ref ( ) . unwrap ( ) ;
174
+ let esplora_url = electrsd . esplora_url . as_ref ( ) . unwrap ( ) ;
298
175
let config_a = random_config ( & esplora_url) ;
299
176
let node_a = Builder :: from_config ( config_a) . build ( ) ;
300
177
node_a. start ( ) . unwrap ( ) ;
@@ -306,7 +183,12 @@ fn channel_open_fails_when_funds_insufficient() {
306
183
node_b. start ( ) . unwrap ( ) ;
307
184
let addr_b = node_b. new_funding_address ( ) . unwrap ( ) ;
308
185
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
+ ) ;
310
192
node_a. sync_wallets ( ) . unwrap ( ) ;
311
193
node_b. sync_wallets ( ) . unwrap ( ) ;
312
194
assert_eq ! ( node_a. on_chain_balance( ) . unwrap( ) . get_spendable( ) , 100000 ) ;
@@ -322,7 +204,8 @@ fn channel_open_fails_when_funds_insufficient() {
322
204
323
205
#[ test]
324
206
fn 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 ( ) ;
326
209
let mut config = random_config ( & esplora_url) ;
327
210
config. esplora_server_url = "https://blockstream.info/testnet/api" . to_string ( ) ;
328
211
config. network = bitcoin:: Network :: Testnet ;
@@ -334,15 +217,16 @@ fn connect_to_public_testnet_esplora() {
334
217
335
218
#[ test]
336
219
fn 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 ( ) ;
338
222
let config = random_config ( & esplora_url) ;
339
223
let node = Builder :: from_config ( config. clone ( ) ) . build ( ) ;
340
224
let expected_node_id = node. node_id ( ) ;
341
225
342
226
let funding_address = node. new_funding_address ( ) . unwrap ( ) ;
343
227
let expected_amount = Amount :: from_sat ( 100000 ) ;
344
228
345
- premine_and_distribute_funds ( vec ! [ funding_address] , expected_amount) ;
229
+ premine_and_distribute_funds ( & bitcoind , & electrsd , vec ! [ funding_address] , expected_amount) ;
346
230
assert_eq ! ( node. on_chain_balance( ) . unwrap( ) . get_total( ) , 0 ) ;
347
231
348
232
node. start ( ) . unwrap ( ) ;
0 commit comments