|
|
@@ -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);
|
|
|
+ }
|
|
|
+}
|