@@ -628,7 +628,6 @@ struct ExecutorKit {
628628struct PaymentEvent {
629629 pubkey : PublicKey ,
630630 absolute_time : SystemTime ,
631- wait_time : Duration ,
632631 destination : NodeInfo ,
633632 capacity : Option < u64 > ,
634633}
@@ -1069,15 +1068,15 @@ impl<C: Clock + 'static> Simulation<C> {
10691068
10701069 // in order to choose a deterministic destination is necessary to sort the nodes by its public key
10711070 executors. sort_by ( |ex1, ex2| ex1. source_info . pubkey . cmp ( & ex2. source_info . pubkey ) ) ;
1072-
1071+ let now = SystemTime :: now ( ) ;
10731072 for executor in executors {
10741073 let pubkey = executor. source_info . pubkey ;
10751074 let payload = PaymentEventPayload {
10761075 executor,
10771076 current_count : 0 ,
10781077 } ;
10791078 payment_event_payloads. insert ( pubkey, payload) ;
1080- generate_payment ( & mut heap, pubkey, 0 , & mut payment_event_payloads) . await ?;
1079+ generate_payment ( & mut heap, pubkey, 0 , & mut payment_event_payloads, now ) . await ?;
10811080 }
10821081
10831082 let listener = self . shutdown_listener . clone ( ) ;
@@ -1097,11 +1096,22 @@ impl<C: Clock + 'static> Simulation<C> {
10971096 match heap. pop( ) {
10981097 Some ( Reverse ( PaymentEvent {
10991098 pubkey,
1100- absolute_time: _,
1101- wait_time,
1099+ absolute_time,
11021100 destination,
11031101 capacity
11041102 } ) ) => {
1103+ let internal_now = SystemTime :: now( ) ;
1104+ let wait_time = match absolute_time. duration_since( internal_now) {
1105+ Ok ( elapsed) => {
1106+ // the output of duration_since is not perfectly round affecting the waiting time
1107+ // and as consequence the results are not deterministic; for this reason
1108+ // it is necessary to round the output.
1109+ Duration :: from_secs( elapsed. as_secs_f64( ) . round( ) as u64 )
1110+ } ,
1111+ Err ( _e) => {
1112+ Duration :: from_secs( 0 )
1113+ }
1114+ } ;
11051115 let payload = payment_event_payloads. get( & pubkey) . ok_or( SimulationError :: PaymentGenerationError (
11061116 PaymentGenerationError ( format!( "executor {} not found" , pubkey) ) ,
11071117 ) ) ?;
@@ -1122,22 +1132,24 @@ impl<C: Clock + 'static> Simulation<C> {
11221132 // a payment amount something has gone wrong (because we should have validated that we can always
11231133 // generate amounts), so we exit.
11241134 let amount = payload. executor. payment_generator. payment_amount( capacity) . map_err( SimulationError :: PaymentGenerationError ) ?;
1125- generate_payment( & mut heap, pubkey, payload. current_count + 1 , & mut payment_event_payloads) . await ?;
11261135 if amount == 0 {
11271136 log:: debug!(
11281137 "Skipping zero amount payment for {source} -> {}." , destination
11291138 ) ;
1139+ generate_payment( & mut heap, pubkey, payload. current_count, & mut payment_event_payloads, SystemTime :: now( ) ) . await ?;
11301140 continue ;
11311141 }
11321142
11331143 // Wait until our time to next payment has elapsed then execute a random amount payment to a random
11341144 // destination.
1145+ let next_payment_count = payload. current_count + 1 ;
11351146 select! {
11361147 biased;
11371148 _ = listener. clone( ) => {
11381149 return Ok ( ( ) )
11391150 } ,
11401151 _ = pe_clock. sleep( wait_time) => {
1152+ generate_payment( & mut heap, pubkey, next_payment_count, & mut payment_event_payloads, SystemTime :: now( ) ) . await ?;
11411153 task_clone. spawn( async move {
11421154 log:: debug!( "Generated payment: {source} -> {}: {amount} msat." , destination) ;
11431155
@@ -1501,19 +1513,19 @@ async fn generate_payment(
15011513 pubkey : PublicKey ,
15021514 current_count : u64 ,
15031515 payloads : & mut HashMap < PublicKey , PaymentEventPayload > ,
1516+ base_time : SystemTime ,
15041517) -> Result < ( ) , SimulationError > {
15051518 let payload = payloads
15061519 . get ( & pubkey)
15071520 . ok_or ( SimulationError :: PaymentGenerationError (
15081521 PaymentGenerationError ( format ! ( "executor {} not found" , pubkey) ) ,
15091522 ) ) ?;
1510- let now = SystemTime :: now ( ) ;
15111523 let wait_time = get_payment_delay (
15121524 current_count,
15131525 & payload. executor . source_info ,
15141526 payload. executor . payment_generator . as_ref ( ) ,
15151527 ) ?;
1516- let absolute_time = now
1528+ let absolute_time = base_time
15171529 . checked_add ( wait_time)
15181530 . ok_or ( "Overflow adding duration" )
15191531 . map_err ( |e| {
@@ -1533,7 +1545,6 @@ async fn generate_payment(
15331545 let payment_event = PaymentEvent {
15341546 pubkey,
15351547 absolute_time,
1536- wait_time,
15371548 destination,
15381549 capacity,
15391550 } ;
@@ -2054,24 +2065,25 @@ mod tests {
20542065 let elapsed = start. elapsed ( ) ;
20552066
20562067 let expected_payment_list = vec ! [
2057- node_2. pubkey,
20582068 node_2. pubkey,
20592069 node_4. pubkey,
20602070 node_2. pubkey,
2061- node_4. pubkey,
20622071 node_2. pubkey,
20632072 node_4. pubkey,
20642073 node_2. pubkey,
2074+ node_2. pubkey,
2075+ node_4. pubkey,
20652076 node_4. pubkey,
20662077 node_4. pubkey,
20672078 ] ;
20682079
2069- // Check that simulation ran 30 because
2080+ // Check that simulation ran 20ish seconds because
20702081 // from activity_1 there are 5 payments with a wait_time of 2s -> 10s
20712082 // from activity_2 there are 5 payments with a wait_time of 4s -> 20s
2083+ // but the wait time is interleave between the payments.
20722084 assert ! (
2073- elapsed > = Duration :: from_secs( 30 ) ,
2074- "Simulation should have run at least for 30s , took {:?}" ,
2085+ elapsed < = Duration :: from_secs( 21 ) ,
2086+ "Simulation should have run no more than 21 , took {:?}" ,
20752087 elapsed
20762088 ) ;
20772089
@@ -2270,7 +2282,9 @@ mod tests {
22702282 "Simulation should have run at least for 25s, took {:?}" ,
22712283 elapsed
22722284 ) ;
2273- let expected_payment_list = vec ! [ pk1, pk2, pk1, pk1, pk1, pk3, pk3, pk2, pk4] ;
2285+ let expected_payment_list = vec ! [
2286+ pk1, pk2, pk1, pk1, pk1, pk3, pk3, pk3, pk4, pk3, pk2, pk1, pk4,
2287+ ] ;
22742288 assert ! (
22752289 payments_list. lock( ) . unwrap( ) . as_ref( ) == expected_payment_list,
22762290 "The expected order of payments is not correct"
0 commit comments