@@ -9,36 +9,51 @@ use electrumd::jsonrpc::serde_json::json;
99use electrumd:: ElectrumD ;
1010
1111use electrs:: chain:: Address ;
12+ use electrs:: electrum:: RPC as ElectrumRPC ;
1213
1314#[ cfg( not( feature = "liquid" ) ) ]
1415use bitcoin:: address;
1516
16- /// Test the Electrum RPC server using an headless Electrum wallet
17- /// This only runs on Bitcoin (non-Liquid) mode.
18- #[ cfg_attr( not( feature = "liquid" ) , test) ]
19- #[ cfg_attr( feature = "liquid" , allow( dead_code) ) ]
20- fn test_electrum ( ) -> Result < ( ) > {
21- // Spawn an Electrs Electrum RPC server
22- let ( electrum_server, electrum_addr, mut tester) = common:: init_electrum_tester ( ) . unwrap ( ) ;
23-
24- // Spawn an headless Electrum wallet RPC daemon, connected to Electrs
25- let mut electrum_wallet_conf = electrumd:: Conf :: default ( ) ;
26- let server_arg = format ! ( "{}:t" , electrum_addr. to_string( ) ) ;
27- electrum_wallet_conf. args = if std:: env:: var_os ( "RUST_LOG" ) . is_some ( ) {
28- vec ! [ "-v" , "--server" , & server_arg]
29- } else {
30- vec ! [ "--server" , & server_arg]
31- } ;
32- electrum_wallet_conf. view_stdout = true ;
33- let electrum_wallet = ElectrumD :: with_conf ( electrumd:: exe_path ( ) ?, & electrum_wallet_conf) ?;
34-
35- let notify_wallet = || {
36- electrum_server. notify ( ) ;
17+ struct WalletTester {
18+ electrum_server : ElectrumRPC ,
19+ electrum_wallet : ElectrumD ,
20+ tester : common:: TestRunner ,
21+ }
22+
23+ impl WalletTester {
24+ fn new ( ) -> Result < Self > {
25+ let ( electrum_server, electrum_addr, tester) = common:: init_electrum_tester ( ) . unwrap ( ) ;
26+
27+ let mut electrum_wallet_conf = electrumd:: Conf :: default ( ) ;
28+ let server_arg = format ! ( "{}:t" , electrum_addr) ;
29+ electrum_wallet_conf. args = if std:: env:: var_os ( "RUST_LOG" ) . is_some ( ) {
30+ vec ! [ "-v" , "--server" , & server_arg]
31+ } else {
32+ vec ! [ "--server" , & server_arg]
33+ } ;
34+ electrum_wallet_conf. view_stdout = true ;
35+ let electrum_wallet =
36+ ElectrumD :: with_conf ( electrumd:: exe_path ( ) ?, & electrum_wallet_conf) ?;
37+
38+ log:: info!(
39+ "Electrum wallet version: {:?}" ,
40+ electrum_wallet. call( "version" , & json!( [ ] ) ) ?
41+ ) ;
42+
43+ Ok ( WalletTester {
44+ electrum_server,
45+ electrum_wallet,
46+ tester,
47+ } )
48+ }
49+
50+ fn notify_wallet ( & self ) {
51+ self . electrum_server . notify ( ) ;
3752 std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 200 ) ) ;
38- } ;
53+ }
3954
40- let assert_balance = | confirmed : f64 , unconfirmed : f64 | {
41- let balance = electrum_wallet. call ( "getbalance" , & json ! ( [ ] ) ) . unwrap ( ) ;
55+ fn assert_balance ( & self , confirmed : f64 , unconfirmed : f64 ) {
56+ let balance = self . electrum_wallet . call ( "getbalance" , & json ! ( [ ] ) ) . unwrap ( ) ;
4257 log:: info!( "balance: {}" , balance) ;
4358
4459 assert_eq ! (
@@ -53,15 +68,16 @@ fn test_electrum() -> Result<()> {
5368 } else {
5469 assert ! ( balance[ "unconfirmed" ] . is_null( ) )
5570 }
56- } ;
71+ }
5772
58- let newaddress = || -> Address {
73+ fn newaddress ( & self ) -> Address {
5974 #[ cfg( not( feature = "liquid" ) ) ]
6075 type ParseAddrType = Address < address:: NetworkUnchecked > ;
6176 #[ cfg( feature = "liquid" ) ]
6277 type ParseAddrType = Address ;
6378
64- let addr = electrum_wallet
79+ let addr = self
80+ . electrum_wallet
6581 . call ( "createnewaddress" , & json ! ( [ ] ) )
6682 . unwrap ( )
6783 . as_str ( )
@@ -73,37 +89,55 @@ fn test_electrum() -> Result<()> {
7389 let addr = addr. assume_checked ( ) ;
7490
7591 addr
76- } ;
92+ }
93+ }
7794
78- log:: info!(
79- "Electrum wallet version: {:?}" ,
80- electrum_wallet. call( "version" , & json!( [ ] ) ) ?
81- ) ;
95+ /// Test balance tracking with confirmed and unconfirmed transactions
96+ #[ cfg_attr( not( feature = "liquid" ) , test) ]
97+ #[ cfg_attr( feature = "liquid" , allow( dead_code) ) ]
98+ fn test_electrum_balance ( ) -> Result < ( ) > {
99+ let mut wt = WalletTester :: new ( ) ?;
100+
101+ let addr1 = wt. newaddress ( ) ;
102+ let addr2 = wt. newaddress ( ) ;
103+
104+ wt. assert_balance ( 0.0 , 0.0 ) ;
105+
106+ wt. tester . send ( & addr1, "0.1 BTC" . parse ( ) . unwrap ( ) ) ?;
107+ wt. notify_wallet ( ) ;
108+ wt. assert_balance ( 0.0 , 0.1 ) ;
82109
83- // Send some funds and verify that the balance checks out
84- let addr1 = newaddress ( ) ;
85- let addr2 = newaddress ( ) ;
110+ wt . tester . mine ( ) ? ;
111+ wt . notify_wallet ( ) ;
112+ wt . assert_balance ( 0.1 , 0.0 ) ;
86113
87- assert_balance ( 0.0 , 0.0 ) ;
114+ wt. tester . send ( & addr2, "0.2 BTC" . parse ( ) . unwrap ( ) ) ?;
115+ wt. notify_wallet ( ) ;
116+ wt. assert_balance ( 0.1 , 0.2 ) ;
88117
89- let txid1 = tester. send ( & addr1 , "0.1 BTC" . parse ( ) . unwrap ( ) ) ?;
90- notify_wallet ( ) ;
91- assert_balance ( 0.0 , 0.1 ) ;
118+ wt . tester . mine ( ) ?;
119+ wt . notify_wallet ( ) ;
120+ wt . assert_balance ( 0.3 , 0.0 ) ;
92121
93- tester. mine ( ) ?;
94- notify_wallet ( ) ;
95- assert_balance ( 0.1 , 0.0 ) ;
122+ Ok ( ( ) )
123+ }
124+
125+ /// Test transaction history via onchain_history
126+ #[ cfg_attr( not( feature = "liquid" ) , test) ]
127+ #[ cfg_attr( feature = "liquid" , allow( dead_code) ) ]
128+ fn test_electrum_history ( ) -> Result < ( ) > {
129+ let mut wt = WalletTester :: new ( ) ?;
96130
97- let txid2 = tester. send ( & addr2, "0.2 BTC" . parse ( ) . unwrap ( ) ) ?;
98- notify_wallet ( ) ;
99- assert_balance ( 0.1 , 0.2 ) ;
131+ let addr1 = wt. newaddress ( ) ;
132+ let addr2 = wt. newaddress ( ) ;
100133
101- tester. mine ( ) ?;
102- notify_wallet ( ) ;
103- assert_balance ( 0.3 , 0.0 ) ;
134+ let txid1 = wt. tester . send ( & addr1, "0.1 BTC" . parse ( ) . unwrap ( ) ) ?;
135+ wt. tester . mine ( ) ?;
136+ let txid2 = wt. tester . send ( & addr2, "0.2 BTC" . parse ( ) . unwrap ( ) ) ?;
137+ wt. tester . mine ( ) ?;
138+ wt. notify_wallet ( ) ;
104139
105- // Verify that the transaction history checks out
106- let history = electrum_wallet. call ( "onchain_history" , & json ! ( [ ] ) ) ?;
140+ let history = wt. electrum_wallet . call ( "onchain_history" , & json ! ( [ ] ) ) ?;
107141 log:: debug!( "history = {:#?}" , history) ;
108142 assert_eq ! (
109143 history[ "transactions" ] [ 0 ] [ "txid" ] . as_str( ) ,
@@ -119,37 +153,47 @@ fn test_electrum() -> Result<()> {
119153 assert_eq ! ( history[ "transactions" ] [ 1 ] [ "height" ] . as_u64( ) , Some ( 103 ) ) ;
120154 assert_eq ! ( history[ "transactions" ] [ 1 ] [ "bc_value" ] . as_str( ) , Some ( "0.2" ) ) ;
121155
122- // Send an outgoing payment
123- electrum_wallet. call (
156+ Ok ( ( ) )
157+ }
158+
159+ /// Test sending an outgoing payment
160+ #[ cfg_attr( not( feature = "liquid" ) , test) ]
161+ #[ cfg_attr( feature = "liquid" , allow( dead_code) ) ]
162+ fn test_electrum_payment ( ) -> Result < ( ) > {
163+ let mut wt = WalletTester :: new ( ) ?;
164+
165+ let addr1 = wt. newaddress ( ) ;
166+ wt. tester . send ( & addr1, "0.3 BTC" . parse ( ) . unwrap ( ) ) ?;
167+ wt. tester . mine ( ) ?;
168+ wt. notify_wallet ( ) ;
169+ wt. assert_balance ( 0.3 , 0.0 ) ;
170+
171+ wt. electrum_wallet . call (
124172 "broadcast" ,
125- & json ! ( [ electrum_wallet. call(
173+ & json ! ( [ wt . electrum_wallet. call(
126174 "payto" ,
127175 & json!( {
128- "destination" : tester. node_client( ) . get_new_address( None , None ) ?,
176+ "destination" : wt . tester. node_client( ) . get_new_address( None , None ) ?,
129177 "amount" : 0.16 ,
130178 "fee" : 0.001 ,
131179 } ) ,
132180 ) ?] ) ,
133181 ) ?;
134- notify_wallet ( ) ;
135- assert_balance ( 0.139 , 0.0 ) ;
182+ wt . notify_wallet ( ) ;
183+ wt . assert_balance ( 0.139 , 0.0 ) ;
136184
137- tester. mine ( ) ?;
138- notify_wallet ( ) ;
139- assert_balance ( 0.139 , 0.0 ) ;
185+ wt . tester . mine ( ) ?;
186+ wt . notify_wallet ( ) ;
187+ wt . assert_balance ( 0.139 , 0.0 ) ;
140188
141189 Ok ( ( ) )
142190}
143191
144192/// Test the Electrum RPC server using a raw TCP socket
145- /// This only runs on Bitcoin (non-Liquid) mode.
146193#[ cfg_attr( not( feature = "liquid" ) , test) ]
147194#[ cfg_attr( feature = "liquid" , allow( dead_code) ) ]
148- #[ ignore = "must be launched singularly, otherwise conflict with the other server" ]
149195fn test_electrum_raw ( ) {
150- // Spawn an Electrs Electrum RPC server
151196 let ( _electrum_server, electrum_addr, mut _tester) = common:: init_electrum_tester ( ) . unwrap ( ) ;
152- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 1000 ) ) ;
153197
154198 let mut stream = TcpStream :: connect ( electrum_addr) . unwrap ( ) ;
155199 let write = "{\" jsonrpc\" : \" 2.0\" , \" method\" : \" server.version\" , \" id\" : 0}" ;
0 commit comments