@@ -25,11 +25,16 @@ use super::connectivity::{
2525} ;
2626use super :: payment:: {
2727 bidirectional_payments, concurrent_payments, pay_expired_invoice, receive_bolt11_payment,
28+ receive_keysend_payment,
2829} ;
2930use super :: { CloseType , PayType , Phase , Side } ;
3031
3132/// Run the standard interop test sequence that is identical across all implementations.
3233///
34+ /// Covers: basic channel cycle (BOLT11 send/receive), disconnect/reconnect, force close
35+ /// (both sides), inbound channels, bidirectional payments, expired invoices, concurrent
36+ /// payments, keysend (send + receive), and fee-change close scenarios.
37+ ///
3338/// Caller must have called `setup_interop_test` before this function.
3439/// Does NOT call `node.stop()` -- caller handles that.
3540pub ( crate ) async fn run_common_tests < E : ElectrumApi > (
@@ -87,6 +92,15 @@ pub(crate) async fn run_common_tests<E: ElectrumApi>(
8792 concurrent_payments ( node, peer, 5 , 1_000_000 ) . await ;
8893 cooperative_close_by_ldk ( node, peer, bitcoind, electrs, & user_ch) . await ;
8994
95+ // Keysend (send + receive in one channel)
96+ let ( user_ch, _ext_ch) =
97+ open_channel_to_external ( node, peer, bitcoind, electrs, 1_000_000 , Some ( 500_000_000 ) ) . await ;
98+ let ext_node_id = peer. get_node_id ( ) . await . unwrap ( ) ;
99+ node. spontaneous_payment ( ) . send ( 5_000_000 , ext_node_id, None ) . unwrap ( ) ;
100+ expect_event ! ( node, PaymentSuccessful ) ;
101+ receive_keysend_payment ( node, peer, 5_000_000 ) . await ;
102+ cooperative_close_by_ldk ( node, peer, bitcoind, electrs, & user_ch) . await ;
103+
90104 // Fee change scenarios
91105 cooperative_close_after_fee_change ( node, peer, bitcoind, electrs) . await ;
92106
@@ -124,6 +138,10 @@ async fn run_combo<E: ElectrumApi>(
124138 node. bolt11_payment ( ) . send ( & parsed, None ) . unwrap ( ) ;
125139 expect_event ! ( node, PaymentSuccessful ) ;
126140 } ,
141+ PayType :: Keysend => {
142+ node. spontaneous_payment ( ) . send ( payment_amount_msat, ext_node_id, None ) . unwrap ( ) ;
143+ expect_event ! ( node, PaymentSuccessful ) ;
144+ } ,
127145 }
128146
129147 close_channel (
@@ -139,7 +157,7 @@ async fn run_combo<E: ElectrumApi>(
139157 . await ;
140158}
141159
142- /// Run all 16 combo permutations (phase × disconnect side × close type × close initiator).
160+ /// Run all 32 combo permutations (phase × disconnect side × close type × close initiator × pay type ).
143161///
144162/// Caller must have called `setup_interop_test` before this function.
145163/// Does NOT call `node.stop()` -- caller handles that.
@@ -164,28 +182,21 @@ pub(crate) async fn run_combos<E: ElectrumApi>(
164182 ( Phase :: Idle , Side :: External , CloseType :: Force , Side :: Ldk ) ,
165183 ( Phase :: Idle , Side :: External , CloseType :: Force , Side :: External ) ,
166184 ] ;
167-
168- for ( i, ( phase, disc, close, initiator) ) in combos. iter ( ) . enumerate ( ) {
169- println ! (
170- "=== combo {}/{}: {:?} {:?} {:?} {:?} ===" ,
171- i + 1 ,
172- combos. len( ) ,
173- phase,
174- disc,
175- close,
176- initiator
177- ) ;
178- run_combo (
179- node,
180- peer,
181- bitcoind,
182- electrs,
183- * phase,
184- * disc,
185- * close,
186- * initiator,
187- PayType :: Bolt11 ,
188- )
189- . await ;
185+ let pay_types = [ PayType :: Bolt11 , PayType :: Keysend ] ;
186+ let total = combos. len ( ) * pay_types. len ( ) ;
187+
188+ let mut i = 0 ;
189+ for ( phase, disc, close, initiator) in combos. iter ( ) {
190+ for pay_type in pay_types. iter ( ) {
191+ i += 1 ;
192+ println ! (
193+ "=== combo {}/{}: {:?} {:?} {:?} {:?} {:?} ===" ,
194+ i, total, phase, disc, close, initiator, pay_type
195+ ) ;
196+ run_combo (
197+ node, peer, bitcoind, electrs, * phase, * disc, * close, * initiator, * pay_type,
198+ )
199+ . await ;
200+ }
190201 }
191202}
0 commit comments