فهرست منبع

merge conflicts

mohab metwally 3 سال پیش
والد
کامیت
6b83239db6

+ 72 - 0
Cargo.lock

@@ -1163,8 +1163,11 @@ dependencies = [
  "darkfi-derive",
  "darkfi-derive-internal",
  "darkfi-sdk",
+ "dashu",
+ "dashu-macros",
  "dirs",
  "ed25519-compact",
+ "env_logger",
  "fast-socks5",
  "futures",
  "futures-rustls",
@@ -1402,6 +1405,56 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "dashu"
+version = "0.2.0"
+source = "git+https://github.com/ertosns/dashu#744c8c546947a1988e6c0710433cd5e58d3af86f"
+dependencies = [
+ "dashu-base",
+ "dashu-float",
+ "dashu-int",
+ "dashu-macros",
+]
+
+[[package]]
+name = "dashu-base"
+version = "0.2.0"
+source = "git+https://github.com/ertosns/dashu#744c8c546947a1988e6c0710433cd5e58d3af86f"
+
+[[package]]
+name = "dashu-float"
+version = "0.2.0"
+source = "git+https://github.com/ertosns/dashu#744c8c546947a1988e6c0710433cd5e58d3af86f"
+dependencies = [
+ "dashu-base",
+ "dashu-int",
+ "static_assertions",
+]
+
+[[package]]
+name = "dashu-int"
+version = "0.2.0"
+source = "git+https://github.com/ertosns/dashu#744c8c546947a1988e6c0710433cd5e58d3af86f"
+dependencies = [
+ "cfg-if 1.0.0",
+ "dashu-base",
+ "num-traits",
+ "rand",
+ "static_assertions",
+]
+
+[[package]]
+name = "dashu-macros"
+version = "0.2.0"
+source = "git+https://github.com/ertosns/dashu#744c8c546947a1988e6c0710433cd5e58d3af86f"
+dependencies = [
+ "dashu-base",
+ "dashu-float",
+ "dashu-int",
+ "proc-macro2",
+ "quote",
+]
+
 [[package]]
 name = "dchat"
 version = "0.1.0"
@@ -1701,6 +1754,19 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "env_logger"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
 [[package]]
 name = "error-chain"
 version = "0.12.4"
@@ -2267,6 +2333,12 @@ version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
 
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
 [[package]]
 name = "iana-time-zone"
 version = "0.1.50"

+ 8 - 1
Cargo.toml

@@ -101,7 +101,7 @@ tungstenite = {version = "0.17.3", optional = true}
 
 # socks5
 fast-socks5 = {version = "0.4.3", optional = true}
-
+            
 # Crypto
 rand = {version = "0.8.5", optional = true}
 blake2b_simd = {version = "1.0.0", optional = true}
@@ -129,6 +129,13 @@ sqlx = {version = "0.6.2", features = ["runtime-async-std-native-tls", "sqlite"]
 # Blockchain store
 sled = {version = "0.34.7", optional = true}
 
+# big float
+dashu = { version = "0.2.0", git = "https://github.com/ertosns/dashu" } 
+dashu-macros = { version = "0.2.0",  git = "https://github.com/ertosns/dashu" }
+
+# env logger
+env_logger = "0.9.1"
+
 [dev-dependencies]
 clap = {version = "3.2.20", features = ["derive"]}
 halo2_proofs = {version = "0.2.0", features = ["dev-graph", "gadget-traces", "sanity-checks"]}

+ 3 - 1
example/crypsinous.rs

@@ -1,5 +1,5 @@
 use ::darkfi::{
-    blockchain::EpochConsensus, net::Settings, stakeholder::Stakeholder, util::time::Timestamp,
+    net::Settings, stakeholder::{Stakeholder, EpochConsensus},util::time::Timestamp,
 };
 
 use clap::Parser;
@@ -7,6 +7,7 @@ use futures::executor::block_on;
 use std::thread;
 use url::Url;
 
+
 #[derive(Parser)]
 struct NetCli {
     #[clap(long, value_parser, default_value = "tls://127.0.0.1:12003")]
@@ -21,6 +22,7 @@ struct NetCli {
 
 #[async_std::main]
 async fn main() {
+    env_logger::init();
     let args = NetCli::parse();
     let addr = vec![Url::parse(args.addr.as_str()).unwrap()];
     let mut peers = vec![];

+ 7 - 5
example/lead.rs

@@ -5,14 +5,15 @@ use pasta_curves::pallas;
 use url::Url;
 
 use darkfi::{
-    blockchain::{epoch::Epoch, EpochConsensus},
     crypto::leadcoin::{LeadCoin, LEAD_PUBLIC_INPUT_LEN},
     net::Settings,
-    stakeholder::Stakeholder,
+    stakeholder::{Stakeholder, epoch::{Epoch, {EpochConsensus}}},
 };
 
+
 fn main() {
-    debug!("..");
+    env_logger::init();
+
     let k: u32 = 13;
     //
 
@@ -44,9 +45,10 @@ fn main() {
 
     let eta: pallas::Base = stakeholder.get_eta();
     let mut epoch = Epoch::new(consensus, eta);
-    // sigma is nubmer of slots * reward (assuming reward is 1 for simplicity)
     let sigma = pallas::Base::from(10);
-    let coins: Vec<Vec<LeadCoin>> = epoch.create_coins(sigma, vec![]);
+    let coins: Vec<Vec<LeadCoin>> = epoch.create_coins(sigma.clone(),
+                                                       sigma,
+                                                       vec![]);
     let coin = coins[0][0];
     let contract = coin.create_contract();
 

+ 0 - 3
src/blockchain/mod.rs

@@ -6,9 +6,6 @@ use crate::{
     Result,
 };
 
-pub mod epoch;
-pub use epoch::{Epoch, EpochConsensus};
-
 pub mod blockstore;
 pub use blockstore::{BlockOrderStore, BlockStore, HeaderStore};
 

+ 5 - 8
src/crypto/leadcoin.rs

@@ -41,7 +41,8 @@ pub struct LeadCoin {
     // election seeds
     pub y_mu: Option<pallas::Base>, // leader election nonce derived from eta at onset of epoch
     pub rho_mu: Option<pallas::Base>, // leader election nonce derived from eta at onset of epoch
-    pub sigma_scalar: Option<pallas::Base>,
+    pub sigma1: Option<pallas::Base>,
+    pub sigma2: Option<pallas::Base>,
 }
 
 impl LeadCoin {
@@ -63,8 +64,7 @@ impl LeadCoin {
         let nonce = self.nonce.unwrap();
         let lottery_msg_input = [root_sk, nonce];
         let lottery_msg: pallas::Base =
-            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
-                .hash(lottery_msg_input);
+            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(lottery_msg_input);
         //
         let po_y_pt: pallas::Point = pedersen_commitment_base(lottery_msg, mod_r_p(y_mu));
         let po_y = *po_y_pt.to_affine().coordinates().unwrap().x();
@@ -72,10 +72,6 @@ impl LeadCoin {
         let po_rho_pt: pallas::Point = pedersen_commitment_base(lottery_msg, mod_r_p(rho_mu));
         let po_rho = *po_rho_pt.to_affine().coordinates().unwrap().x();
 
-        let _zero = pallas::Base::from(0);
-
-        // ===============
-
         let cm_pos = self.idx;
         let cm_root = {
             let pos: u32 = cm_pos;
@@ -129,7 +125,8 @@ impl LeadCoin {
             mau_rho: Value::known(mod_r_p(self.rho_mu.unwrap())),
             mau_y: Value::known(mod_r_p(self.y_mu.unwrap())),
             root_cm: Value::known(self.root_cm.unwrap()),
-            sigma_scalar: Value::known(self.sigma_scalar.unwrap()),
+            sigma1: Value::known(self.sigma1.unwrap()),
+            sigma2: Value::known(self.sigma2.unwrap()),
         }
     }
 }

+ 4 - 0
src/stakeholder/consts.rs

@@ -0,0 +1,4 @@
+pub(crate) const RADIX_BITS : usize = 76;
+pub(crate) const LOG_T: &str = "stakeholder";
+pub(crate)const TREE_LEN: usize = 100;
+pub(crate) const P: &str = "28948022309329048855892746252171976963363056481941560715954676764349967630337";

+ 53 - 24
src/blockchain/epoch.rs → src/stakeholder/epoch.rs

@@ -22,18 +22,29 @@ use crate::crypto::{
     proof::{Proof, ProvingKey},
     types::DrkValueBlind,
     util::{mod_r_p, pedersen_commitment_base, pedersen_commitment_u64},
+    keypair::{Keypair,SecretKey},
+
 };
+use crate::stakeholder::utils::{fbig2ibig, base2ibig};
+
+use dashu::float::{DBig, FBig, round::{mode::{HalfAway, Zero}, Rounding::*}};
+use dashu::integer::{IBig,UBig,Sign};
+
+use crate::stakeholder::Float10;
+use crate::stakeholder::consts::{RADIX_BITS};
+
 
 const PRF_NULLIFIER_PREFIX: u64 = 0;
 const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
 
+
 /// epoch configuration
 /// this struct need be a singleton,
 /// TODO should be populated from configuration file.
 #[derive(Copy, Debug, Default, Clone)]
 pub struct EpochConsensus {
     pub sl_len: u64, // length of slot in terms of ticks
-    /// number of slots per epoch
+    // number of slots per epoch
     pub e_len: u64, // length of epoch in terms of slots
     pub tick_len: u64, // length of tick in terms of seconds
     pub reward: u64, // constant reward value for the slot leader
@@ -54,6 +65,9 @@ impl EpochConsensus {
         }
     }
 
+    pub fn total_stake(&self, e: u64, sl: u64) -> u64 {
+        (e*self.e_len +  sl+ 1) * self.reward
+    }
     /// getter for constant stakeholder reward
     /// used for configuring the stakeholder reward value
     pub fn get_reward(&self) -> u64 {
@@ -176,7 +190,7 @@ impl Epoch {
     }
 
     //note! the strategy here is single competing coin per slot.
-    pub fn create_coins(&mut self, sigma: pallas::Base, owned: Vec<OwnCoin>) -> Vec<Vec<LeadCoin>> {
+    pub fn create_coins(&mut self, sigma1: pallas::Base, sigma2: pallas::Base, owned: Vec<OwnCoin>) -> Vec<Vec<LeadCoin>> {
         let mut rng = thread_rng();
         let mut seeds: Vec<u64> = vec![];
         for _i in 0..self.len() {
@@ -194,7 +208,8 @@ impl Epoch {
                 let mut slot_coins = vec![];
                 for elem in &owned {
                     let coin = self.create_leadcoin(
-                        sigma,
+                        sigma1,
+                        sigma2,
                         elem.note.value,
                         i,
                         root_sks[i],
@@ -208,8 +223,15 @@ impl Epoch {
             }
             // otherwise compete with zero stake
             else {
-                let coin =
-                    self.create_leadcoin(sigma, 0, i, root_sks[i], path_sks[i], seeds[i], sks[i]);
+                let coin = self.create_leadcoin(sigma1,
+                                                sigma2,
+                                                0,
+                                                i,
+                                                root_sks[i],
+                                                path_sks[i],
+                                                seeds[i],
+                                                sks[i]
+                );
                 self.coins.push(vec![coin]);
             }
         }
@@ -218,7 +240,8 @@ impl Epoch {
 
     pub fn create_leadcoin(
         &self,
-        sigma: pallas::Base,
+        sigma1: pallas::Base,
+        sigma2: pallas::Base,
         value: u64,
         i: usize,
         c_root_sk: MerkleNode,
@@ -301,7 +324,8 @@ impl Epoch {
             c2_blind: Some(c_cm2_blind),
             y_mu: Some(y_mu),
             rho_mu: Some(rho_mu),
-            sigma_scalar: Some(sigma),
+            sigma1: Some(sigma1),
+            sigma2: Some(sigma2),
         };
         coin
     }
@@ -324,26 +348,31 @@ impl Epoch {
         for (winning_idx, coin) in competing_coins.iter().enumerate() {
             let y_exp = [coin.root_sk.unwrap(), coin.nonce.unwrap()];
             let y_exp_hash: pallas::Base =
-                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
-                )
-                .hash(y_exp);
-            // pick x coordinate of y for comparison
+                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(y_exp);
+            //TODO (fix) use the hash of y coordinates, using single coordinate is insecure.
+            //  pick x coordinate of y for comparison
             let y_x: pallas::Base =
                 *pedersen_commitment_base(coin.y_mu.unwrap(), mod_r_p(y_exp_hash))
-                    .to_affine()
-                    .coordinates()
-                    .unwrap()
-                    .x();
-            let ord = pallas::Base::from(10241024); //TODO fine tune this scalar.
-            let target = ord * pallas::Base::from(coin.value.unwrap());
-            debug!("y_x: {:?}, target: {:?}", y_x, target);
-            //TODO (FIX) reversed for testin
-            let iam_leader = target < y_x;
-            if iam_leader && coin.value.unwrap() > highest_stake {
-                highest_stake = coin.value.unwrap();
-                highest_stake_idx = winning_idx;
+                .to_affine()
+                .coordinates()
+                .unwrap().x();
+            let val_2ibig = Float10::try_from(coin.value.unwrap())
+                .unwrap()
+                .with_precision(RADIX_BITS)
+                .value();
+            let target = base2ibig(coin.sigma1.unwrap()) * val_2ibig.clone() +
+                base2ibig(coin.sigma2.unwrap()) * val_2ibig.clone() * val_2ibig;
+            let target_ibig = fbig2ibig(target);
+            let y_ibig = base2ibig(y_x);
+            debug!("y_x: {}, target: {}", y_ibig, target_ibig);
+            let iam_leader =  y_ibig < target_ibig ;
+            if iam_leader {
+                if coin.value.unwrap() > highest_stake {
+                    highest_stake = coin.value.unwrap();
+                    highest_stake_idx = winning_idx;
+                }
+                am_leader.push(iam_leader);
             }
-            am_leader.push(iam_leader);
         }
         *idx = highest_stake_idx;
         !am_leader.is_empty()

+ 82 - 9
src/stakeholder/mod.rs

@@ -9,8 +9,12 @@ use rand::rngs::OsRng;
 use smol::Executor;
 use url::Url;
 
+pub mod types;
+pub mod consts;
+pub mod utils;
+
 use crate::{
-    blockchain::{Blockchain, Epoch, EpochConsensus},
+    blockchain::{Blockchain},
     consensus::{
         clock::{Clock, Ticks},
         Block, BlockInfo, Header, LeadProof, Metadata,
@@ -37,12 +41,26 @@ use crate::{
         Transaction,
     },
     util::{path::expand_path, time::Timestamp},
-    zk::circuit::{BurnContract, LeadContract, MintContract},
+
+    stakeholder::types::{Float10},
+    stakeholder::consts::{RADIX_BITS, LOG_T, TREE_LEN, P},
+    stakeholder::utils::{fbig2base},
     Result,
 };
 
-const LOG_T: &str = "stakeholder";
-const TREE_LEN: usize = 100;
+use url::Url;
+
+use pasta_curves::pallas;
+
+use group::ff::PrimeField;
+
+
+use dashu::float::{DBig, FBig, round::{mode::{HalfAway, Zero}, Rounding::*}};
+use dashu::integer::{IBig};
+use dashu_macros::fbig;
+
+pub mod epoch;
+pub use epoch::{Epoch, EpochConsensus};
 
 #[derive(Debug)]
 pub struct SlotWorkspace {
@@ -443,11 +461,11 @@ impl Stakeholder {
             match self.clock.ticks().await {
                 Ticks::GENESIS { e, sl } => {
                     //TODO (res) any initialization happening here?
-                    self.new_epoch();
+                    self.new_epoch(e, sl);
                     self.new_slot(e, sl);
                 }
                 Ticks::NEWEPOCH { e, sl } => {
-                    self.new_epoch();
+                    self.new_epoch(e, sl);
                     self.new_slot(e, sl);
                 }
                 Ticks::NEWSLOT { e, sl } => self.new_slot(e, sl),
@@ -484,10 +502,23 @@ impl Stakeholder {
         }
     }
 
+    fn get_f(&self) -> Float10 {
+        //TODO (res) should be function of the average time to end of slot
+        // in the previous epoch.
+        let one : Float10 = Float10::from_str_native("1")
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        let two : Float10 = Float10::from_str_native("2")
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        one/two
+    }
     /// on the onset of the epoch, layout the new the competing coins
     /// assuming static stake during the epoch, enforced by the commitment to competing coins
     /// in the epoch's gen2esis data.
-    fn new_epoch(&mut self) {
+    fn new_epoch(&mut self, e: u64, sl: u64) {
         info!(target: LOG_T, "[new epoch] {}", self);
         let eta = self.get_eta();
         let mut epoch = Epoch::new(self.epoch_consensus, eta);
@@ -500,11 +531,53 @@ impl Stakeholder {
         // set to one untill then.
         let reward = pallas::Base::one();
         let num_slots = num_slots + epochs * epoch_len;
-        let sigma: pallas::Base = pallas::Base::from(num_slots) * reward;
-        epoch.create_coins(sigma, self.ownedcoins.clone()); // set epoch interal fields working space with competing coins
+        //
+        let f = self.get_f();
+        let total_stake = self.epoch.consensus.total_stake(e, sl);
+        let one : Float10 = Float10::from_str_native("1")
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        let two : Float10 = Float10::from_str_native("2")
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        //TODO should set f precision here
+        /*
+        let f : Float10 =  Float10::try_from(f_val)
+            .unwrap()
+            .with_precision(RADIX_BITS)
+        .value();
+        */
+        let mut field_p = Float10::from_str_native(P)
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        let total_sigma  = Float10::try_from(total_stake)
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        let x = one - f;
+        info!("x: {}", x);
+        // also ln small x should work normally.
+        let c = x.ln();
+        info!("c: {}", c);
+        let sigma1_fbig = c.clone()/total_sigma.clone() * field_p.clone();
+        info!("sigma1: {}", sigma1_fbig);
+
+        //TODO in sigma calculation get rad if exp is neg
+        let sigma1 : pallas::Base = fbig2base(sigma1_fbig);
+        info!("sigma1 base: {:?}", sigma1);
+        let sigma2_fbig = c.clone()/total_sigma.clone() * c.clone()/total_sigma.clone()  * field_p.clone()/two.clone();
+        info!("sigma2: {}", sigma2_fbig);
+        let sigma2 : pallas::Base = fbig2base(sigma2_fbig);
+        info!("sigma2 base: {:?}", sigma2);
+        epoch.create_coins(sigma1, sigma2, self.ownedcoins.clone()); // set epoch interal fields working space with competing coins
         self.epoch = epoch.clone();
     }
 
+
+
     /// at the begining of the slot
     /// stakeholder need to play the lottery for the slot.
     /// FIXME if the stakeholder is not winning, staker can try different coins before,

+ 4 - 0
src/stakeholder/types.rs

@@ -0,0 +1,4 @@
+use dashu::float::{DBig, FBig, round::{mode::{HalfAway, Zero}, Rounding::*}};
+use dashu::integer::{IBig};
+
+pub(crate) type Float10 = FBig<Zero,10>;

+ 86 - 0
src/stakeholder/utils.rs

@@ -0,0 +1,86 @@
+use pasta_curves::pallas;
+use group::ff::PrimeField;
+use dashu::float::{DBig, FBig, round::{mode::{HalfAway, Zero}, Rounding::*}};
+use dashu::integer::{IBig, Sign, UBig};
+use crate::stakeholder::Float10;
+use crate::stakeholder::consts::{RADIX_BITS};
+use log::{info};
+
+pub(crate) fn fbig2ibig(f: Float10) -> IBig {
+    info!("fbig -> ibig (f): {}", f);
+    let rad = IBig::try_from(10).unwrap();
+    let sig = f.repr().significand();
+    let exp = f.repr().exponent();
+    let val : IBig = if exp>=0 {
+        sig.clone()*rad.pow(exp as usize)
+    } else {
+        sig.clone()
+    };
+    info!("fbig -> ibig (i): {}", val);
+    val
+}
+
+
+pub(crate) fn base2ibig(base: pallas::Base) -> IBig {
+    //
+    let byts : [u8; 32] = base.to_repr();
+    let words : [u64; 4] = [
+        u64::from_le_bytes(byts[0..8].try_into().expect("")),
+        u64::from_le_bytes(byts[8..16].try_into().expect("")),
+        u64::from_le_bytes(byts[16..24].try_into().expect("")),
+        u64::from_le_bytes(byts[24..32].try_into().expect(""))
+    ];
+    let uparts = UBig::from_words(&words);
+    //TODO both y, and t are positive, but workout the sign for general use
+    let ibig = IBig::from_parts(Sign::Positive, uparts);
+    ibig
+}
+
+pub(crate) fn fbig2base(f: Float10) -> pallas::Base {
+    info!("fbig -> base (f): {}", f);
+    let val : IBig = fbig2ibig(f);
+    let (sign, word) = val.as_sign_words();
+    //TODO (res) set pallas base sign, i.e sigma1 is negative.
+    let mut words : [u64;4] = [0,0,0,0];
+    for i in 0..word.len() {
+        words[i] = word[i];
+    }
+    let base = match sign {
+        Sign::Positive => pallas::Base::from_raw(words),
+        Sign::Negative => pallas::Base::from_raw(words).neg(),
+    };
+    base
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::stakeholder::utils::{base2ibig, fbig2base, fbig2ibig};
+    use crate::stakeholder::consts::{RADIX_BITS};
+    use pasta_curves::pallas;
+    use dashu::float::{DBig, FBig, round::{mode::{HalfAway, Zero}, Rounding::*}};
+    use dashu::integer::{IBig};
+    use crate::stakeholder::Float10;
+    #[test]
+    fn dashu_fbig2ibig() {
+        let f = Float10::from_str_native("234234223.000")
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        let i : IBig = fbig2ibig(f);
+        let sig = IBig::from(234234223);
+        assert_eq!(i, sig);
+    }
+
+    #[test]
+    fn dashu_test_base2ibig() {
+        //
+        let fbig : Float10 = Float10::from_str_native("28948022309329048855892746252171976963363056481941560715954676764349967630337")
+            .unwrap()
+            .with_precision(RADIX_BITS)
+            .value();
+        let ibig = fbig2ibig(fbig.clone());
+        let res_base : pallas::Base = fbig2base(fbig.clone());
+        let res_ibig : IBig = base2ibig(res_base);
+        assert_eq!(res_ibig, ibig);
+    }
+}

+ 27 - 11
src/zk/circuit/lead_contract.rs

@@ -127,7 +127,8 @@ pub struct LeadContract {
     pub mau_rho: Value<pallas::Scalar>,
     pub mau_y: Value<pallas::Scalar>,
     pub root_cm: Value<pallas::Scalar>,
-    pub sigma_scalar: Value<pallas::Base>,
+    pub sigma1: Value<pallas::Base>,
+    pub sigma2: Value<pallas::Base>,
     //pub eta : Option<u32>,
     //pub rho : Option<u32>,
     //pub h : Option<u32>, // hash of this data
@@ -269,6 +270,7 @@ impl Circuit<pallas::Base> for LeadContract {
         config: Self::Config,
         mut layouter: impl Layouter<pallas::Base>,
     ) -> Result<(), Error> {
+
         let less_than_chip = config.lessthan_chip();
         NativeRangeCheckChip::<WINDOW_SIZE, NUM_OF_BITS, NUM_OF_WINDOWS>::load_k_table(
             &mut layouter,
@@ -327,11 +329,16 @@ impl Circuit<pallas::Base> for LeadContract {
         let sk: AssignedCell<Fp, Fp> =
             self.load_private(layouter.namespace(|| "sk"), config.advices[0], self.sk).unwrap();
 
-        // sigma scalar is 2^254/(total network stake + epsilon)
-        let sigma_scalar = self.load_private(
-            layouter.namespace(|| "load scalar "),
+        let sigma1 = self.load_private(
+            layouter.namespace(|| "load sigma1 "),
+            config.advices[0],
+            self.sigma1,
+        )?;
+
+        let sigma2 = self.load_private(
+            layouter.namespace(|| "load sigma2 "),
             config.advices[0],
-            self.sigma_scalar,
+            self.sigma2,
         )?;
 
         // leadership coefficient used for fine-tunning leader election frequency
@@ -593,17 +600,25 @@ impl Circuit<pallas::Base> for LeadContract {
         };
         let rho_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         let rho_commit_base = rho_commit.inner().x();
-        // stakeholder absolute stake + 1 (epsilon)
-        let stake_plus = ar_chip.add(layouter.namespace(|| ""), &one, &coin_value)?;
-        let target =
-            ar_chip.mul(layouter.namespace(|| "calculate target"), &sigma_scalar, &stake_plus)?;
 
-        let y: Value<pallas::Base> = y_commit_base.value().cloned();
+
+        let term1 = ar_chip.mul(layouter.namespace(|| "calculate term1"), &sigma1, &coin_value.clone())?;
+
+        let term2_1 = ar_chip.mul(layouter.namespace(|| "calculate term2_1"), &sigma2, &coin_value.clone())?;
+
+        let term2 = ar_chip.mul(layouter.namespace(|| "calculate term2"), &term2_1, &coin_value.clone())?;
+
+        let target = ar_chip.add(layouter.namespace(|| "calculate target"), &term1, &term2)?;
+        let target = ar_chip.mul(layouter.namespace(|| ""), &one, &coin_value.clone())?;
         let target: Value<pallas::Base> = target.value().cloned();
+
+        let y: Value<pallas::Base> = y_commit_base.value().cloned();
+
+
         less_than_chip.witness_less_than(
             layouter.namespace(|| "y < target"),
-            target, //reversed for testing
             y,
+            target,
             0,
             true,
         )?;
@@ -664,5 +679,6 @@ impl Circuit<pallas::Base> for LeadContract {
         )?;
 
         Ok(())
+
     }
 }