@@ -225,56 +225,79 @@ mod test {
225225
226226 use super :: * ;
227227
228- // TODO: move to regular fns, rework step
229- fn first_non_zero ( stake : BigInt , total_currency : BigInt , step : BigInt ) -> BigInt {
230- let ten = BigInt :: from_str ( "10" ) . unwrap ( ) ;
231- let mut stake = stake;
232- if step == BigInt :: zero ( ) {
233- stake + BigInt :: one ( )
234- } else {
235- loop {
236- let thrs = Threshold :: new ( stake. clone ( ) , total_currency. clone ( ) ) ;
237-
238- if thrs. threshold_rational != BigRational :: zero ( ) {
239- println ! ( "stake: {stake} nanoMINA" ) ;
240- return first_non_zero ( stake - step. clone ( ) , total_currency, step / ten) ;
228+ #[ test]
229+ fn test_threshold_nonzero ( ) {
230+ /// Binary search to find the exact point where threshold becomes non-zero
231+ fn binary_search ( total_currency : BigInt ) -> BigInt {
232+ let mut low = BigInt :: zero ( ) ;
233+ let mut high = total_currency. clone ( ) ;
234+ while low < high {
235+ let mid: BigInt = ( & low + & high) / 2 ;
236+ let thrs = Threshold :: new ( mid. clone ( ) , total_currency. clone ( ) ) ;
237+
238+ if thrs. threshold_rational == BigRational :: zero ( ) {
239+ low = mid + BigInt :: one ( ) ;
240+ } else {
241+ high = mid. clone ( ) ;
241242 }
242- stake += step. clone ( ) ;
243243 }
244+ low
244245 }
245- }
246-
247- #[ test]
248- #[ ignore]
249- fn test_threshold_nonzero ( ) {
250- // let total_currency = BigInt::from_str("1157953132840039233").unwrap();
251- // let initial_stake = BigInt::zero();
252- // let initial_step = BigInt::from_str("10000000000000000000").unwrap();
253-
254- let total_currency = BigInt :: from_str ( "1025422352000001000" ) . unwrap ( ) ;
255- let initial_stake = BigInt :: zero ( ) ;
256- let initial_step = BigInt :: from_str ( "10000000000000000000" ) . unwrap ( ) ;
257-
258- let first_non_zero_nanomina =
259- first_non_zero ( initial_stake, total_currency. clone ( ) , initial_step) ;
260246
261- let last_zero = first_non_zero_nanomina. clone ( ) - BigInt :: one ( ) ;
247+ // Different total currency values to test
248+ let test_cases = vec ! [
249+ ( "1025422352000001000" , "Test case 1" ) , // Original value
250+ ( "1157953132840039233" , "Test case 2" ) , // Another value from comments
251+ ( "1000000000000000000" , "1 billion MINA" ) , // 1 billion MINA
252+ ( "5000000000000000000" , "5 billion MINA" ) , // 5 billion MINA
253+ ( "10000000000000000000" , "10 billion MINA" ) , // 10 billion MINA
254+ ( "100000000000000000" , "100 million MINA" ) , // 100 million MINA
255+ ] ;
256+
257+ for ( total_currency_str, description) in test_cases {
258+ let total_currency = BigInt :: from_str ( total_currency_str) . unwrap ( ) ;
259+
260+ let first_non_zero_stake = binary_search ( total_currency. clone ( ) ) ;
261+
262+ // Verify we found the exact transition point
263+ assert ! (
264+ first_non_zero_stake > BigInt :: zero( ) && first_non_zero_stake <= total_currency,
265+ "First non-zero stake should be between 1 and total_currency for {}" ,
266+ description
267+ ) ;
262268
263- let thrs_zero = Threshold :: new ( last_zero, total_currency. clone ( ) ) ;
264- assert_eq ! ( thrs_zero. threshold_rational, BigRational :: zero( ) ) ;
269+ // Verify the transition point
270+ let last_zero_stake = & first_non_zero_stake - BigInt :: one ( ) ;
271+ let thrs_zero = Threshold :: new ( last_zero_stake, total_currency. clone ( ) ) ;
272+ assert_eq ! (
273+ thrs_zero. threshold_rational,
274+ BigRational :: zero( ) ,
275+ "Threshold should be zero for stake one less than first non-zero for {}" ,
276+ description
277+ ) ;
265278
266- let thrs_first = Threshold :: new ( first_non_zero_nanomina. clone ( ) , total_currency) ;
267- assert ! ( thrs_first. threshold_rational > BigRational :: zero( ) ) ;
279+ let thrs_first = Threshold :: new ( first_non_zero_stake. clone ( ) , total_currency. clone ( ) ) ;
280+ assert ! (
281+ thrs_first. threshold_rational > BigRational :: zero( ) ,
282+ "Threshold should be non-zero for first non-zero stake for {}" ,
283+ description
284+ ) ;
268285
269- let first_non_zero_mina = first_non_zero_nanomina. to_f64 ( ) . unwrap ( ) / 1_000_000_000.0 ;
286+ // Convert to MINA for display
287+ let first_non_zero_mina = first_non_zero_stake. to_f64 ( ) . unwrap ( ) / 1_000_000_000.0 ;
270288
271- println ! ( "First non zero stake: {first_non_zero_mina} MINA" ) ;
272- println ! (
273- "First non zero threshold: {}" ,
274- thrs_first. threshold_rational. to_f64( ) . unwrap( )
275- ) ;
289+ println ! (
290+ "First non-zero stake: {} nanoMINA ({:.6} MINA)" ,
291+ first_non_zero_stake, first_non_zero_mina
292+ ) ;
293+ println ! (
294+ "First non-zero threshold: {:.15}" ,
295+ thrs_first. threshold_rational. to_f64( ) . unwrap( )
296+ ) ;
297+ }
276298 }
277299
300+
278301 #[ test]
279302 #[ ignore]
280303 fn test_threshold_increase ( ) {
0 commit comments