Răsfoiți Sursa

unit test sigmas accuracy

mohab metwally 3 ani în urmă
părinte
comite
59cd6b982d
1 a modificat fișierele cu 76 adăugiri și 6 ștergeri
  1. 76 6
      src/consensus/state.rs

+ 76 - 6
src/consensus/state.rs

@@ -247,24 +247,44 @@ impl ConsensusState {
     pub fn sigmas(&mut self) -> (pallas::Base, pallas::Base) {
         let f = self.win_inv_prob_with_full_stake();
         let total_stake = self.total_stake();
-        info!(target: "consensus::state", "sigmas(): f: {}", f);
-        info!(target: "consensus::state", "sigmas(): stake: {}", total_stake);
+
+        let total_sigma =
+            Float10::try_from(total_stake).unwrap().with_precision(constants::RADIX_BITS).value();
+        Self::calc_sigmas(f, total_sigma)
+    }
+
+    fn calc_sigmas(f: Float10, total_sigma: Float10) -> (pallas::Base, pallas::Base) {
+        info!("sigmas(): f: {}", f);
+        info!("sigmas(): stake: {:}", total_sigma);
+
         let one = constants::FLOAT10_ONE.clone();
+        let neg_one = constants::FLOAT10_NEG_ONE.clone();
         let two = constants::FLOAT10_TWO.clone();
-        let field_p = Float10::try_from(constants::P).unwrap();
-        let total_sigma = Float10::try_from(total_stake).unwrap();
+
+
+        let field_p = Float10::from_str_native(constants::P)
+            .unwrap()
+            .with_precision(constants::RADIX_BITS)
+            .value();
+
 
         let x = one - f;
         let c = x.ln();
+        let neg_c = neg_one * c;
 
-        let sigma1_fbig = c.clone() / total_sigma.clone() * field_p.clone();
+        let sigma1_fbig =  neg_c.clone() / total_sigma.clone() * field_p.clone();
+        println!("sigma1_fbig: {:}", sigma1_fbig);
         let sigma1 = fbig2base(sigma1_fbig);
 
-        let sigma2_fbig = (c / total_sigma).powf(two.clone()) * (field_p / two);
+
+        let sigma2_fbig = (neg_c / total_sigma).powf(two.clone()) * (field_p / two);
+        println!("sigma2_fbig: {:}", sigma2_fbig);
         let sigma2 = fbig2base(sigma2_fbig);
+
         (sigma1, sigma2)
     }
 
+
     /// Generate coins for provided sigmas.
     /// NOTE: The strategy here is having a single competing coin per slot.
     // TODO: DRK coin need to be burned, and consensus coin to be minted.
@@ -525,6 +545,7 @@ impl ConsensusState {
         } else if f >= constants::FLOAT10_ONE.clone() {
             f = constants::MAX_F.clone()
         }
+        /*
         let hist_len = self.leaders_history.len();
         if hist_len > 3 &&
             self.leaders_history[hist_len - 1] == 0 &&
@@ -534,6 +555,7 @@ impl ConsensusState {
         {
             f =  f.clone() * constants::DEG_RATE.clone().powf(self.zero_leads_len());
         }
+        */
         // log f history
         let file = File::options().append(true).open(constants::F_HISTORY_LOG).unwrap();
         {
@@ -1018,3 +1040,51 @@ impl From<ForkInfo> for Fork {
         Self { genesis_block: fork_info.genesis_block, sequence }
     }
 }
+
+#[cfg(test)]
+mod tests {
+
+    use darkfi_sdk::{
+        pasta::{group::ff::PrimeField, pallas},
+    };
+    use log::info;
+
+    use crate::consensus::{
+        constants,
+        state::ConsensusState,
+        utils::fbig2base,
+        Float10,
+    };
+
+    use crate::{ Error, Result};
+    use dashu::base::Abs;
+
+    use std::io::{prelude::*, BufWriter};
+    use std::fs::File;
+
+    #[test]
+    fn calc_sigmas_test() {
+        let giga_epsilon = Float10::from_str_native("10000000000000000000000000000000000000000000000000000000000").unwrap();
+        let giga_epsilon_base = fbig2base(giga_epsilon);
+        let f = Float10::from_str_native("0.5").unwrap();
+        let total_stake = Float10::from_str_native("1000").unwrap();
+        let (sigma1, sigma2) = ConsensusState::calc_sigmas(f, total_stake);
+        let sigma1_rhs = Float10::from_str_native("20065240046497827749443820209808913616958821867408735207193448041041362944").unwrap();
+        let sigma1_rhs_base = fbig2base(sigma1_rhs);
+        let sigma2_rhs = Float10::from_str_native("6954082282744237239883318512759812991231744634473746668074299461468160").unwrap();
+        let sigma2_rhs_base = fbig2base(sigma2_rhs);
+        let sigma1_delta = if sigma1_rhs_base>sigma1 {
+            sigma1_rhs_base - sigma1
+        } else {
+            sigma1 - sigma1_rhs_base
+        };
+        let sigma2_delta = if sigma2_rhs_base > sigma2 {
+            sigma2_rhs_base - sigma2
+        } else {
+            sigma2 - sigma2_rhs_base
+        };
+        //note! test cases were generated by low precision scripts.
+        assert!(sigma1_delta < giga_epsilon_base);
+        assert!(sigma2_delta < giga_epsilon_base);
+    }
+}