ソースを参照

[consensus] exponentially decreasing pid proportions

mohab metwally 3 年 前
コミット
fe2055c934
3 ファイル変更40 行追加14 行削除
  1. 4 3
      src/consensus/constants.rs
  2. 6 6
      src/consensus/leadcoin.rs
  3. 30 5
      src/consensus/state.rs

+ 4 - 3
src/consensus/constants.rs

@@ -45,14 +45,15 @@ lazy_static! {
     pub static ref  DT: Float10 =  Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref  DT: Float10 =  Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref  TI: Float10 = FLOAT10_ONE.clone();
     pub static ref  TI: Float10 = FLOAT10_ONE.clone();
     pub static ref  TD: Float10 = FLOAT10_ONE.clone();
     pub static ref  TD: Float10 = FLOAT10_ONE.clone();
-    pub static ref  KP: Float10 = Float10::from_str_native("0.2").unwrap().with_precision(RADIX_BITS).value();
-    pub static ref  KI: Float10 = Float10::from_str_native("0.043").unwrap().with_precision(RADIX_BITS).value();
+    pub static ref  KP: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
+    pub static ref  KI: Float10 = Float10::from_str_native("0.04").unwrap().with_precision(RADIX_BITS).value();
     pub static ref  KD: Float10 = FLOAT10_ONE.clone();
     pub static ref  KD: Float10 = FLOAT10_ONE.clone();
     pub static ref PID_OUT_STEP: Float10  = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref PID_OUT_STEP: Float10  = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref MAX_DER: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref MAX_DER: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref MIN_DER: Float10 = Float10::from_str_native("-0.1").unwrap().with_precision(RADIX_BITS).value();
     pub static ref MIN_DER: Float10 = Float10::from_str_native("-0.1").unwrap().with_precision(RADIX_BITS).value();
-    pub static ref MAX_F: Float10 = Float10::from_str_native("0.8").unwrap().with_precision(RADIX_BITS).value();
+    pub static ref MAX_F: Float10 = Float10::from_str_native("0.9").unwrap().with_precision(RADIX_BITS).value();
     pub static ref MIN_F: Float10 = Float10::from_str_native("0.05").unwrap().with_precision(RADIX_BITS).value();
     pub static ref MIN_F: Float10 = Float10::from_str_native("0.05").unwrap().with_precision(RADIX_BITS).value();
+    pub static ref DEG_RATE: Float10 = Float10::from_str_native("0.9").unwrap().with_precision(RADIX_BITS).value();
 
 
 }
 }
 
 

+ 6 - 6
src/consensus/leadcoin.rs

@@ -27,7 +27,7 @@ use darkfi_sdk::{
 };
 };
 use halo2_proofs::{arithmetic::Field, circuit::Value};
 use halo2_proofs::{arithmetic::Field, circuit::Value};
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
-use log::debug;
+use log::info;
 use rand::rngs::OsRng;
 use rand::rngs::OsRng;
 
 
 use super::constants::EPOCH_LENGTH;
 use super::constants::EPOCH_LENGTH;
@@ -128,7 +128,7 @@ impl LeadCoin {
         let pk = Self::util_pk(coin1_sk_root, tau);
         let pk = Self::util_pk(coin1_sk_root, tau);
         // Derive the nonce for coin2
         // Derive the nonce for coin2
         let coin2_seed = Self::util_derived_rho(coin1_sk_root, pallas::Base::from(seed));
         let coin2_seed = Self::util_derived_rho(coin1_sk_root, pallas::Base::from(seed));
-        debug!("coin2_seed[{}]: {:?}", slot_index, coin2_seed);
+        info!("coin2_seed[{}]: {:?}", slot_index, coin2_seed);
         let coin1_commitment =
         let coin1_commitment =
             Self::commitment(pk, pallas::Base::from(value), pallas::Base::from(seed), coin1_blind);
             Self::commitment(pk, pallas::Base::from(value), pallas::Base::from(seed), coin1_blind);
         // Hash its coordinates to get a base field element
         // Hash its coordinates to get a base field element
@@ -192,7 +192,7 @@ impl LeadCoin {
 
 
     /// Derive election seeds from given parameters
     /// Derive election seeds from given parameters
     pub fn election_seeds(eta: pallas::Base, slot: pallas::Base) -> (pallas::Base, pallas::Base) {
     pub fn election_seeds(eta: pallas::Base, slot: pallas::Base) -> (pallas::Base, pallas::Base) {
-        debug!("election_seeds: eta: {:?}, slot: {:?}", eta, slot);
+        info!("election_seeds: eta: {:?}, slot: {:?}", eta, slot);
         let election_seed_nonce = pallas::Base::from(3);
         let election_seed_nonce = pallas::Base::from(3);
         let election_seed_lead = pallas::Base::from(22);
         let election_seed_lead = pallas::Base::from(22);
 
 
@@ -286,8 +286,8 @@ impl LeadCoin {
         let value = pallas::Base::from(self.value);
         let value = pallas::Base::from(self.value);
         let target = sigma1 * value + sigma2 * value * value;
         let target = sigma1 * value + sigma2 * value * value;
 
 
-        debug!("is_leader(): y = {:?}", y);
-        debug!("is_leader(): T = {:?}", target);
+        info!("is_leader(): y = {:?}", y);
+        info!("is_leader(): T = {:?}", target);
 
 
         let first_winning = y < target;
         let first_winning = y < target;
         first_winning
         first_winning
@@ -317,7 +317,7 @@ impl LeadCoin {
         &self,
         &self,
         coin_commitment_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
         coin_commitment_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
     ) -> LeadCoin {
     ) -> LeadCoin {
-        debug!("derive_coin(): Deriving new coin!");
+        info!("derive_coin(): Deriving new coin!");
         let derived_c1_rho = self.derived_rho();
         let derived_c1_rho = self.derived_rho();
         let blind = pallas::Scalar::random(&mut OsRng);
         let blind = pallas::Scalar::random(&mut OsRng);
         let derived_c2_cm = Self::commitment(
         let derived_c2_cm = Self::commitment(

+ 30 - 5
src/consensus/state.rs

@@ -217,8 +217,8 @@ impl ConsensusState {
         if total_stake == 0 {
         if total_stake == 0 {
             total_stake = constants::GENESIS_TOTAL_STAKE;
             total_stake = constants::GENESIS_TOTAL_STAKE;
         }
         }
-        debug!("sigmas(): f: {}", f);
-        debug!("sigmas(): stake: {}", total_stake);
+        info!("sigmas(): f: {}", f);
+        info!("sigmas(): stake: {}", total_stake);
         let one = constants::FLOAT10_ONE.clone();
         let one = constants::FLOAT10_ONE.clone();
         let two = constants::FLOAT10_TWO.clone();
         let two = constants::FLOAT10_TWO.clone();
         let field_p = Float10::from_str_native(constants::P)
         let field_p = Float10::from_str_native(constants::P)
@@ -394,6 +394,19 @@ impl ConsensusState {
         constants::KI.clone() * self.f_int()
         constants::KI.clone() * self.f_int()
     }
     }
 
 
+    fn zero_leads_len(&self) -> Float10 {
+        let mut count = constants::FLOAT10_ZERO.clone();
+        let hist_len = self.leaders_history.len();
+        for i in 1..hist_len {
+            if self.leaders_history[hist_len - i] == 0 {
+                count = count + constants::FLOAT10_ONE.clone();
+            } else {
+                break
+            }
+        }
+        count
+    }
+
     /// the probability inverse of winnig lottery having all the stake
     /// the probability inverse of winnig lottery having all the stake
     /// returns f
     /// returns f
     fn win_inv_prob_with_full_stake(&mut self) -> Float10 {
     fn win_inv_prob_with_full_stake(&mut self) -> Float10 {
@@ -403,10 +416,20 @@ impl ConsensusState {
         info!("win_inv_prob_with_full_stake(): PID P: {:?}", p);
         info!("win_inv_prob_with_full_stake(): PID P: {:?}", p);
         info!("win_inv_prob_with_full_stake(): PID I: {:?}", i);
         info!("win_inv_prob_with_full_stake(): PID I: {:?}", i);
         info!("win_inv_prob_with_full_stake(): PID D: {:?}", d);
         info!("win_inv_prob_with_full_stake(): PID D: {:?}", d);
-        let f = p + i + d;
+        let f = p + i.clone() + d;
         info!("win_inv_prob_with_full_stake(): PID f: {}", f);
         info!("win_inv_prob_with_full_stake(): PID f: {}", f);
         if f == constants::FLOAT10_ZERO.clone() {
         if f == constants::FLOAT10_ZERO.clone() {
             return constants::MIN_F.clone()
             return constants::MIN_F.clone()
+        } else if f >= constants::FLOAT10_ONE.clone() {
+            return constants::MAX_F.clone()
+        }
+        let hist_len = self.leaders_history.len();
+        if self.leaders_history[hist_len - 1] == 0 &&
+            self.leaders_history[hist_len - 2] == 0 &&
+            self.leaders_history[hist_len - 3] == 0 &&
+            i.clone() == constants::FLOAT10_ZERO.clone()
+        {
+            return f * constants::DEG_RATE.clone().powf(self.zero_leads_len())
         }
         }
         f
         f
     }
     }
@@ -417,14 +440,16 @@ impl ConsensusState {
     /// * 'sigma1', 'sigma2': slot sigmas
     /// * 'sigma1', 'sigma2': slot sigmas
     /// Returns: (check: bool, idx: usize) where idx is the winning coin's index
     /// Returns: (check: bool, idx: usize) where idx is the winning coin's index
     pub fn is_slot_leader(&mut self, sigma1: pallas::Base, sigma2: pallas::Base) -> (bool, usize) {
     pub fn is_slot_leader(&mut self, sigma1: pallas::Base, sigma2: pallas::Base) -> (bool, usize) {
-        let competing_coins = &self.coins;
+        let competing_coins = &self.coins.clone();
 
 
         let mut won = false;
         let mut won = false;
         let mut highest_stake = 0;
         let mut highest_stake = 0;
         let mut highest_stake_idx = 0;
         let mut highest_stake_idx = 0;
-
+        let total_stake = self.total_stake();
         for (winning_idx, coin) in competing_coins.iter().enumerate() {
         for (winning_idx, coin) in competing_coins.iter().enumerate() {
             info!("is_slot_leader: coin stake: {:?}", coin.value);
             info!("is_slot_leader: coin stake: {:?}", coin.value);
+            info!("is_slot_leader: total stake: {}", total_stake);
+            info!("is_slot_leader: relative stake: {}", (coin.value as f64) / total_stake as f64);
             let first_winning = coin.is_leader(sigma1, sigma2);
             let first_winning = coin.is_leader(sigma1, sigma2);
             if first_winning && !won {
             if first_winning && !won {
                 highest_stake_idx = winning_idx;
                 highest_stake_idx = winning_idx;