unit test sigmas accuracy

This commit is contained in:
mohab metwally
2023-01-12 00:46:51 +02:00
parent 65648e55cb
commit 59cd6b982d

View File

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