@@ -1610,7 +1610,7 @@ async fn track_payment_result(
16101610
16111611#[ cfg( test) ]
16121612mod tests {
1613- use crate :: clock:: SimulationClock ;
1613+ use crate :: clock:: { Clock , SimulationClock } ;
16141614 use crate :: test_utils:: { MockLightningNode , TestNodesResult } ;
16151615 use crate :: {
16161616 get_payment_delay, test_utils, test_utils:: LightningTestNodeBuilder , LightningError ,
@@ -2005,6 +2005,21 @@ mod tests {
20052005 } ) ;
20062006 }
20072007
2008+ /// Fixed pubkeys for payment ordering tests. Payment events that are scheduled for the same
2009+ /// instant are tie-broken on their source pubkey, so node keys must be stable across runs
2010+ /// for the order of payments to be deterministic.
2011+ fn fixed_test_pubkeys ( ) -> Vec < PublicKey > {
2012+ [
2013+ "02f6dc1fcf3431f461ff5e6d870f286e134b064fddd3795a98d5903c55e76cfa8c" ,
2014+ "0363a5321c2778e2f13f4d7602a84e866824551b4bd31fdfc66e044a274863d647" ,
2015+ "037b0c8a943a6bc3ebb5b56ed1c377a1d3e6b68e9231ad9bf7afd45ba37374f7a3" ,
2016+ "026389dd21b3611bf4bb78f8939d5912f3175107ff9c14b6881bb4bef0e7c6e905" ,
2017+ ]
2018+ . iter ( )
2019+ . map ( |pk| PublicKey :: from_str ( pk) . unwrap ( ) )
2020+ . collect ( )
2021+ }
2022+
20082023 #[ allow( clippy:: type_complexity) ]
20092024 /// Helper to create and configure mock nodes for testing
20102025 async fn setup_test_nodes_for_testing_deterministic_events (
@@ -2053,10 +2068,12 @@ mod tests {
20532068 ( network, payments_list)
20542069 }
20552070
2056- #[ tokio:: test]
2071+ // Run on a paused runtime so that the payment interval sleeps auto-advance rather than
2072+ // consuming real time; elapsed time is measured against the simulation's virtual clock.
2073+ #[ tokio:: test( start_paused = true ) ]
20572074 async fn test_deterministic_payments_events_defined_activities ( ) {
20582075 let ( network, payments_list) =
2059- setup_test_nodes_for_testing_deterministic_events ( None ) . await ;
2076+ setup_test_nodes_for_testing_deterministic_events ( Some ( fixed_test_pubkeys ( ) ) ) . await ;
20602077
20612078 // Define two activities
20622079 // Activity 1: From node_1 to node_2
@@ -2081,29 +2098,34 @@ mod tests {
20812098
20822099 let ( shutdown_trigger, shutdown_listener) = triggered:: trigger ( ) ;
20832100
2101+ let clock = Arc :: new ( SimulationClock :: new ( SystemTime :: now ( ) ) ) ;
2102+
20842103 // Create simulation without a timeout.
20852104 let simulation = Simulation :: new (
20862105 SimulationCfg :: new ( None , 100 , 2.0 , None , None ) ,
20872106 network. get_client_hashmap ( ) ,
20882107 TaskTracker :: new ( ) ,
2089- Arc :: new ( SimulationClock :: new ( SystemTime :: now ( ) ) ) ,
2108+ clock . clone ( ) ,
20902109 shutdown_trigger,
20912110 shutdown_listener,
20922111 ) ;
20932112
20942113 // Run the simulation
2095- let start = std :: time :: Instant :: now ( ) ;
2114+ let start = clock . now ( ) ;
20962115 let _ = simulation. run ( & vec ! [ activity_1, activity_2] ) . await ;
2097- let elapsed = start. elapsed ( ) ;
2116+ let elapsed = clock . now ( ) . duration_since ( start) . unwrap ( ) ;
20982117
2118+ // Activity 1 pays at t = 2, 4, 6, 8, 10 and activity 2 at t = 4, 8, 12, 16, 20. At the
2119+ // instants where both activities fire (t = 4, 8), activity 1 dispatches first because
2120+ // simultaneous events are ordered by source pubkey and its source sorts first.
20992121 let expected_payment_list = vec ! [
2122+ network. nodes[ 1 ] . pubkey,
21002123 network. nodes[ 1 ] . pubkey,
21012124 network. nodes[ 3 ] . pubkey,
21022125 network. nodes[ 1 ] . pubkey,
21032126 network. nodes[ 1 ] . pubkey,
21042127 network. nodes[ 3 ] . pubkey,
21052128 network. nodes[ 1 ] . pubkey,
2106- network. nodes[ 1 ] . pubkey,
21072129 network. nodes[ 3 ] . pubkey,
21082130 network. nodes[ 3 ] . pubkey,
21092131 network. nodes[ 3 ] . pubkey,
@@ -2121,57 +2143,47 @@ mod tests {
21212143
21222144 assert ! (
21232145 payments_list. lock( ) . unwrap( ) . as_ref( ) == expected_payment_list,
2124- "The expected order of payments is not correct"
2146+ "The expected order of payments is not correct: {:?} vs {:?}" ,
2147+ payments_list. lock( ) . unwrap( ) ,
2148+ expected_payment_list,
21252149 ) ;
21262150 }
21272151
2128- #[ tokio:: test]
2152+ // Run on a paused runtime so that the payment interval sleeps auto-advance rather than
2153+ // consuming real time; elapsed time is measured against the simulation's virtual clock.
2154+ #[ tokio:: test( start_paused = true ) ]
21292155 async fn test_deterministic_payments_events_random ( ) {
2130- let pk1 = PublicKey :: from_str (
2131- "02f6dc1fcf3431f461ff5e6d870f286e134b064fddd3795a98d5903c55e76cfa8c" ,
2132- )
2133- . unwrap ( ) ;
2134- let pk2 = PublicKey :: from_str (
2135- "0363a5321c2778e2f13f4d7602a84e866824551b4bd31fdfc66e044a274863d647" ,
2136- )
2137- . unwrap ( ) ;
2138- let pk3 = PublicKey :: from_str (
2139- "037b0c8a943a6bc3ebb5b56ed1c377a1d3e6b68e9231ad9bf7afd45ba37374f7a3" ,
2140- )
2141- . unwrap ( ) ;
2142- let pk4 = PublicKey :: from_str (
2143- "026389dd21b3611bf4bb78f8939d5912f3175107ff9c14b6881bb4bef0e7c6e905" ,
2144- )
2145- . unwrap ( ) ;
2156+ let pks = fixed_test_pubkeys ( ) ;
2157+ let ( pk1, pk2, pk3, pk4) = ( pks[ 0 ] , pks[ 1 ] , pks[ 2 ] , pks[ 3 ] ) ;
21462158
21472159 let ( network, payments_list) =
2148- setup_test_nodes_for_testing_deterministic_events ( Some ( vec ! [ pk1 , pk2 , pk3 , pk4 ] ) ) . await ;
2160+ setup_test_nodes_for_testing_deterministic_events ( Some ( pks ) ) . await ;
21492161
21502162 let ( shutdown_trigger, shutdown_listener) = triggered:: trigger ( ) ;
21512163
2164+ let clock = Arc :: new ( SimulationClock :: new ( SystemTime :: now ( ) ) ) ;
2165+
21522166 // Create simulation with a defined seed.
21532167 let simulation = Simulation :: new (
21542168 SimulationCfg :: new ( Some ( 25 ) , 100 , 2.0 , None , Some ( 42 ) ) ,
21552169 network. get_client_hashmap ( ) ,
21562170 TaskTracker :: new ( ) ,
2157- Arc :: new ( SimulationClock :: new ( SystemTime :: now ( ) ) ) ,
2171+ clock . clone ( ) ,
21582172 shutdown_trigger,
21592173 shutdown_listener,
21602174 ) ;
21612175
21622176 // Run the simulation
2163- let start = std :: time :: Instant :: now ( ) ;
2177+ let start = clock . now ( ) ;
21642178 let _ = simulation. run ( & [ ] ) . await ;
2165- let elapsed = start. elapsed ( ) ;
2179+ let elapsed = clock . now ( ) . duration_since ( start) . unwrap ( ) ;
21662180
21672181 assert ! (
21682182 elapsed >= Duration :: from_secs( 25 ) ,
21692183 "Simulation should have run at least for 25s, took {:?}" ,
21702184 elapsed
21712185 ) ;
2172- let expected_payment_list = vec ! [
2173- pk1, pk2, pk1, pk1, pk1, pk3, pk3, pk3, pk4, pk3, pk2, pk1, pk4,
2174- ] ;
2186+ let expected_payment_list = vec ! [ pk1, pk1, pk2, pk2, pk4, pk2, pk2, pk2, pk3, pk3] ;
21752187
21762188 assert ! (
21772189 payments_list. lock( ) . unwrap( ) . as_ref( ) == expected_payment_list,
0 commit comments