@@ -4,6 +4,7 @@ use bitcoin::Network;
44use csv:: WriterBuilder ;
55use lightning:: ln:: features:: NodeFeatures ;
66use lightning:: ln:: PaymentHash ;
7+ use rand:: Rng ;
78use random_activity:: RandomActivityError ;
89use serde:: { Deserialize , Serialize } ;
910use std:: collections:: HashSet ;
@@ -129,6 +130,47 @@ pub struct SimParams {
129130 pub activity : Vec < ActivityParser > ,
130131}
131132
133+ /// Either a value or a range parsed from the simulation file.
134+ #[ derive( Debug , Clone , Copy , Serialize , Deserialize ) ]
135+ #[ serde( untagged) ]
136+ pub enum ValueOrRange < T > {
137+ Value ( T ) ,
138+ Range ( T , T ) ,
139+ }
140+
141+ impl < T > ValueOrRange < T >
142+ where
143+ T : std:: cmp:: PartialOrd + rand_distr:: uniform:: SampleUniform + Copy ,
144+ {
145+ /// Get the enclosed value. If value is defined as a range, sample from it uniformly at random.
146+ pub fn value ( & self ) -> T {
147+ match self {
148+ ValueOrRange :: Value ( x) => * x,
149+ ValueOrRange :: Range ( x, y) => {
150+ let mut rng = rand:: thread_rng ( ) ;
151+ rng. gen_range ( * x..* y)
152+ } ,
153+ }
154+ }
155+ }
156+
157+ impl < T > Display for ValueOrRange < T >
158+ where
159+ T : Display ,
160+ {
161+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
162+ match self {
163+ ValueOrRange :: Value ( x) => write ! ( f, "{x}" ) ,
164+ ValueOrRange :: Range ( x, y) => write ! ( f, "({x}-{y})" ) ,
165+ }
166+ }
167+ }
168+
169+ /// The payment amount in msat. Either a value or a range.
170+ type Amount = ValueOrRange < u64 > ;
171+ /// The interval of seconds between payments. Either a value or a range.
172+ type Interval = ValueOrRange < u16 > ;
173+
132174/// Data structure used to parse information from the simulation file. It allows source and destination to be
133175/// [NodeId], which enables the use of public keys and aliases in the simulation description.
134176#[ derive( Debug , Clone , Serialize , Deserialize ) ]
@@ -146,9 +188,11 @@ pub struct ActivityParser {
146188 #[ serde( default ) ]
147189 pub count : Option < u64 > ,
148190 /// The interval of the event, as in every how many seconds the payment is performed.
149- pub interval_secs : u16 ,
191+ #[ serde( with = "serializers::serde_value_or_range" ) ]
192+ pub interval_secs : Interval ,
150193 /// The amount of m_sat to used in this payment.
151- pub amount_msat : u64 ,
194+ #[ serde( with = "serializers::serde_value_or_range" ) ]
195+ pub amount_msat : Amount ,
152196}
153197
154198/// Data structure used internally by the simulator. Both source and destination are represented as [PublicKey] here.
@@ -164,9 +208,9 @@ pub struct ActivityDefinition {
164208 /// The number of payments to send over the course of the simulation.
165209 pub count : Option < u64 > ,
166210 /// The interval of the event, as in every how many seconds the payment is performed.
167- pub interval_secs : u16 ,
211+ pub interval_secs : Interval ,
168212 /// The amount of m_sat to used in this payment.
169- pub amount_msat : u64 ,
213+ pub amount_msat : Amount ,
170214}
171215
172216#[ derive( Debug , Error ) ]
@@ -731,7 +775,7 @@ impl Simulation {
731775 description. destination . clone ( ) ,
732776 Duration :: from_secs ( description. start_secs . into ( ) ) ,
733777 description. count ,
734- Duration :: from_secs ( description. interval_secs . into ( ) ) ,
778+ description. interval_secs ,
735779 description. amount_msat ,
736780 ) ;
737781
0 commit comments