@@ -171,7 +171,141 @@ mod e2e {
171171 . write_all ( format ! ( "{line}\n " ) . as_bytes ( ) )
172172 . await
173173 . expect ( "Failed to write to stdout" ) ;
174- if line. contains ( "Payjoin sent" ) {
174+ if line. contains ( "Payjoin sent" )
175+ || line. contains ( "Fallback transaction broadcasted" )
176+ {
177+ let _ = tx. send ( true ) . await ;
178+ break ;
179+ }
180+ }
181+ } ) ;
182+
183+ let timeout = tokio:: time:: Duration :: from_secs ( 10 ) ;
184+ let payjoin_sent = tokio:: time:: timeout ( timeout, rx. recv ( ) )
185+ . await
186+ . unwrap_or ( Some ( false ) ) // timed out
187+ . expect ( "rx channel closed prematurely" ) ; // recv() returned None
188+
189+ terminate ( cli_receiver) . await . expect ( "Failed to kill payjoin-cli" ) ;
190+ terminate ( cli_sender) . await . expect ( "Failed to kill payjoin-cli" ) ;
191+
192+ payjoin_sent
193+ } )
194+ . await ?;
195+
196+ assert ! ( payjoin_sent, "Payjoin send was not detected" ) ;
197+
198+ Ok ( ( ) )
199+ }
200+
201+ #[ cfg( feature = "v1" ) ]
202+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 4 ) ]
203+ async fn send_receive_payjoin_v1_fallback_transaction_handling ( ) -> Result < ( ) , BoxError > {
204+ use payjoin_test_utils:: local_cert_key;
205+
206+ let ( bitcoind, _sender, _receiver) = init_bitcoind_sender_receiver ( None , None ) ?;
207+ let temp_dir = tempdir ( ) ?;
208+ let receiver_db_path = temp_dir. path ( ) . join ( "receiver_db" ) ;
209+ let sender_db_path = temp_dir. path ( ) . join ( "sender_db" ) ;
210+
211+ let payjoin_sent = tokio:: spawn ( async move {
212+ let receiver_rpchost = format ! ( "http://{}/wallet/receiver" , bitcoind. params. rpc_socket) ;
213+ let sender_rpchost = format ! ( "http://{}/wallet/sender" , bitcoind. params. rpc_socket) ;
214+ let cookie_file = & bitcoind. params . cookie_file ;
215+ let pj_endpoint = "https://localhost" ;
216+ let payjoin_cli = env ! ( "CARGO_BIN_EXE_payjoin-cli" ) ;
217+
218+ let cert = local_cert_key ( ) ;
219+ let cert_path = & temp_dir. path ( ) . join ( "localhost.crt" ) ;
220+ tokio:: fs:: write ( cert_path, cert. cert . der ( ) . to_vec ( ) )
221+ . await
222+ . expect ( "must be able to write self signed certificate" ) ;
223+
224+ let key_path = & temp_dir. path ( ) . join ( "localhost.key" ) ;
225+ tokio:: fs:: write ( key_path, cert. signing_key . serialize_der ( ) )
226+ . await
227+ . expect ( "must be able to write self signed certificate" ) ;
228+
229+ let mut cli_receiver = Command :: new ( payjoin_cli)
230+ . arg ( "--root-certificate" )
231+ . arg ( cert_path)
232+ . arg ( "--certificate-key" )
233+ . arg ( key_path)
234+ . arg ( "--bip78" )
235+ . arg ( "--rpchost" )
236+ . arg ( & receiver_rpchost)
237+ . arg ( "--cookie-file" )
238+ . arg ( cookie_file)
239+ . arg ( "--db-path" )
240+ . arg ( & receiver_db_path)
241+ . arg ( "receive" )
242+ . arg ( RECEIVE_SATS )
243+ . arg ( "--port" )
244+ . arg ( "0" )
245+ . arg ( "--pj-endpoint" )
246+ . arg ( "https://dfdkfkdj.codm" )
247+ . stdout ( Stdio :: piped ( ) )
248+ . stderr ( Stdio :: inherit ( ) )
249+ . spawn ( )
250+ . expect ( "Failed to execute payjoin-cli" ) ;
251+
252+ let stdout =
253+ cli_receiver. stdout . take ( ) . expect ( "Failed to take stdout of child process" ) ;
254+ let reader = BufReader :: new ( stdout) ;
255+ let mut stdout = tokio:: io:: stdout ( ) ;
256+ let mut bip21 = String :: new ( ) ;
257+
258+ let mut lines = reader. lines ( ) ;
259+
260+ while let Some ( line) = lines. next_line ( ) . await . expect ( "Failed to read line from stdout" )
261+ {
262+ // Write to stdout regardless
263+ stdout
264+ . write_all ( format ! ( "{line}\n " ) . as_bytes ( ) )
265+ . await
266+ . expect ( "Failed to write to stdout" ) ;
267+
268+ if line. to_ascii_uppercase ( ) . starts_with ( "BITCOIN" ) {
269+ bip21 = line;
270+ break ;
271+ }
272+ }
273+ tracing:: debug!( "Got bip21 {}" , & bip21) ;
274+
275+ let mut cli_sender = Command :: new ( payjoin_cli)
276+ . arg ( "--root-certificate" )
277+ . arg ( cert_path)
278+ . arg ( "--bip78" )
279+ . arg ( "--rpchost" )
280+ . arg ( & sender_rpchost)
281+ . arg ( "--cookie-file" )
282+ . arg ( cookie_file)
283+ . arg ( "--db-path" )
284+ . arg ( & sender_db_path)
285+ . arg ( "send" )
286+ . arg ( & bip21)
287+ . arg ( "--fee-rate" )
288+ . arg ( "1" )
289+ . stdout ( Stdio :: piped ( ) )
290+ . stderr ( Stdio :: inherit ( ) )
291+ . spawn ( )
292+ . expect ( "Failed to execute payjoin-cli" ) ;
293+
294+ let stdout = cli_sender. stdout . take ( ) . expect ( "Failed to take stdout of child process" ) ;
295+ let reader = BufReader :: new ( stdout) ;
296+ let ( tx, mut rx) = tokio:: sync:: mpsc:: channel ( 1 ) ;
297+
298+ let mut lines = reader. lines ( ) ;
299+ tokio:: spawn ( async move {
300+ let mut stdout = tokio:: io:: stdout ( ) ;
301+ while let Some ( line) =
302+ lines. next_line ( ) . await . expect ( "Failed to read line from stdout" )
303+ {
304+ stdout
305+ . write_all ( format ! ( "{line}\n " ) . as_bytes ( ) )
306+ . await
307+ . expect ( "Failed to write to stdout" ) ;
308+ if line. contains ( "Fallback transaction broadcasted" ) {
175309 let _ = tx. send ( true ) . await ;
176310 break ;
177311 }
@@ -621,50 +755,4 @@ mod e2e {
621755
622756 Ok ( ( ) )
623757 }
624-
625- /// Test that verifies fallback transaction is broadcasted when payjoin fails (V1)
626- #[ tokio:: test]
627- async fn test_v1_fallback_transaction_broadcast_on_payjoin_failure ( ) -> Result < ( ) , BoxError > {
628- use payjoin_test_utils:: local_cert_key;
629-
630- let ( bitcoind, _sender, _receiver) = init_bitcoind_sender_receiver ( None , None ) ?;
631- let temp_dir = tempdir ( ) ?;
632- let sender_db_path = temp_dir. path ( ) . join ( "sender.db" ) ;
633- let receiver_db_path = temp_dir. path ( ) . join ( "receiver.db" ) ;
634-
635- let receiver_rpchost = format ! ( "http://{}/wallet/receiver" , bitcoind. params. rpc_socket) ;
636- let sender_rpchost = format ! ( "http://{}/wallet/sender" , bitcoind. params. rpc_socket) ;
637- let cookie_file = & bitcoind. params . cookie_file ;
638- let payjoin_cli = env ! ( "CARGO_BIN_EXE_payjoin-cli" ) ;
639-
640- let cert = local_cert_key ( ) ;
641- let cert_path = & temp_dir. path ( ) . join ( "localhost.crt" ) ;
642- tokio:: fs:: write ( cert_path, cert. cert . der ( ) . to_vec ( ) )
643- . await
644- . expect ( "must be able to write self signed certificate" ) ;
645-
646- Ok ( ( ) )
647- }
648-
649- /// Test that verifies fallback transaction is broadcasted when payjoin fails (V2)
650- #[ tokio:: test]
651- async fn test_v2_fallback_transaction_broadcast_on_payjoin_failure ( ) -> Result < ( ) , BoxError > {
652- use payjoin_test_utils:: local_cert_key;
653-
654- let ( bitcoind, _sender, _receiver) = init_bitcoind_sender_receiver ( None , None ) ?;
655- let temp_dir = tempdir ( ) ?;
656- let sender_db_path = temp_dir. path ( ) . join ( "sender.db" ) ;
657-
658- let sender_rpchost = format ! ( "http://{}/wallet/sender" , bitcoind. params. rpc_socket) ;
659- let cookie_file = & bitcoind. params . cookie_file ;
660- let payjoin_cli = env ! ( "CARGO_BIN_EXE_payjoin-cli" ) ;
661-
662- let cert = local_cert_key ( ) ;
663- let cert_path = & temp_dir. path ( ) . join ( "localhost.crt" ) ;
664- tokio:: fs:: write ( cert_path, cert. cert . der ( ) . to_vec ( ) )
665- . await
666- . expect ( "must be able to write self signed certificate" ) ;
667-
668- Ok ( ( ) )
669- }
670758}
0 commit comments