Преглед изворни кода

WIP debugging failing verified lead contract

mohab metwally пре 3 година
родитељ
комит
f27ee17282

+ 3 - 3
example/crypsinous.rs

@@ -172,9 +172,9 @@ async fn start(args: NetCli, ex: Arc<Executor<'_>>) -> Result<()> {
     p2p.clone().start(ex.clone()).await?;
     ex2.spawn(p2p.clone().run(ex.clone())).detach();
 
-    let slots = 3;
-    let epochs = 3;
-    let ticks = 10;
+    let slots = 10;
+    let epochs = 6;
+    let ticks = 30;
     let reward = 1;
     let epoch_consensus = EpochConsensus::new(Some(slots), Some(epochs), Some(ticks), Some(reward));
 

+ 11 - 11
script/research/crypsinous_playground/src/main.rs

@@ -52,7 +52,7 @@ struct Args {
     #[structopt(long, default_value = "changeme")]
     /// Password for the wallet database
     wallet_pass: String,
-    
+
     #[structopt(short, default_value = "1")]
     /// How many epochs to simulate
     epochs: u64,
@@ -75,15 +75,15 @@ async fn realmain(args: Args, _ex: Arc<smol::Executor<'_>>) -> Result<()>  {
         return Ok(());
     }
     info!("Simulation epochs: {}", epochs);
-    
+
     // Initialize wallet that holds coins for staking
     let wallet = init_wallet(&args.wallet_path, &args.wallet_pass).await?;
-    
+
     // Initialize client
     let client = Arc::new(Client::new(wallet.clone()).await?);
-    
+
     // Retrieving nodes wallet coins
-    let mut owned = client.get_own_coins().await?;    
+    let mut owned = client.get_own_coins().await?;
     // If node holds no coins in its wallet, we generate some new staking coins
     if owned.is_empty() {
         info!("Node wallet is empty, generating new staking coins...");
@@ -93,12 +93,12 @@ async fn realmain(args: Args, _ex: Arc<smol::Executor<'_>>) -> Result<()>  {
     // owned = vec![];
     info!("Node coins: {:?}", owned);
 
-    // Generating leader proof keys    
-    let k: u32 = 13; // Proof rows number
+    // Generating leader proof keys
+    let k: u32 = 11; // Proof rows number
     info!("Generating proof keys with k: {}", k);
     let proving_key = ProvingKey::build(k, &LeadContract::default());
     let verifying_key = VerifyingKey::build(k, &LeadContract::default());
-    
+
     // Simulating epochs with 10 slots
     for epoch in 0..epochs {
         info!("Epoch {} started!", epoch);
@@ -106,7 +106,7 @@ async fn realmain(args: Args, _ex: Arc<smol::Executor<'_>>) -> Result<()>  {
         // TODO: Retrieve previous lead proof
         let eta = pallas::Base::one();
         let epoch_coins = coins::create_epoch_coins(eta, &owned, epoch, 0);
-        info!("Generated epoch_coins: {}", epoch_coins.len());    
+        info!("Generated epoch_coins: {}", epoch_coins.len());
         for slot in 0..10 {
             // Checking if slot leader
             info!("Slot {} started!", slot);
@@ -132,6 +132,6 @@ async fn realmain(args: Args, _ex: Arc<smol::Executor<'_>>) -> Result<()>  {
             }
         }
     }
-    
-    Ok(()) 
+
+    Ok(())
 }

+ 1 - 1
src/consensus/clock.rs

@@ -96,7 +96,7 @@ impl Clock {
     async fn ticking(&self) -> bool {
         let (abs, rel, _) = self.tick_time().await;
         debug!("abs time to genesis ticks: {}, rel ticks: {}", abs, rel);
-        rel < (self.tick_len) / 3
+        rel < (self.tick_len)*2 / 3
     }
 
     pub async fn sync(&mut self) -> Result<()> {

+ 34 - 30
src/consensus/coins.rs

@@ -44,6 +44,7 @@ use crate::{
     Result,
 };
 use darkfi_sdk::crypto::{constants::MERKLE_DEPTH_ORCHARD, MerkleNode, Nullifier};
+use incrementalmerkletree::Hashable;
 
 const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
 
@@ -117,10 +118,11 @@ fn create_coins(
     let mut tree_cm = BridgeTree::<MerkleNode, MERKLE_DEPTH>::new(*EPOCH_LENGTH as usize);
     // Leadcoins matrix were each row represents a slot and contains its competing coins.
     let mut coins: Vec<Vec<LeadCoin>> = vec![];
-    for i in 0..*EPOCH_LENGTH {
-        let index = i as usize;
-        // Use existing stake
-        if !owned.is_empty() {
+
+    // Use existing stake
+    if !owned.is_empty() {
+        for i in 0..*EPOCH_LENGTH {
+            let index = i as usize;
             let mut slot_coins = vec![];
             for elem in owned {
                 let coin = create_leadcoin(
@@ -140,23 +142,25 @@ fn create_coins(
             coins.push(slot_coins);
             continue
         }
-
-        // Compete with zero stake
-        let coin = create_leadcoin(
-            eta,
-            sigma1,
-            sigma2,
-            *LOTTERY_HEAD_START,
-            index,
-            root_sks[index],
-            path_sks[index],
-            seeds[index],
-            sks[index],
-            &mut tree_cm,
-        );
-        coins.push(vec![coin]);
+    } else {
+        for i in 0..*EPOCH_LENGTH {
+            let index = i as usize;
+            // Compete with zero stake
+            let coin = create_leadcoin(
+                eta,
+                sigma1,
+                sigma2,
+                *LOTTERY_HEAD_START,
+                index,
+                root_sks[index],
+                path_sks[index],
+                seeds[index],
+                sks[index],
+                &mut tree_cm,
+            );
+            coins.push(vec![coin]);
+        }
     }
-
     coins
 }
 
@@ -262,13 +266,14 @@ fn create_leadcoin(
     let leaf_position = tree_cm.witness();
     let c_root_cm = tree_cm.root(0).unwrap();
     let c_cm_path = tree_cm.authentication_path(leaf_position.unwrap(), &c_root_cm).unwrap();
+
     /*
     let c_root_cm = {
         let mut current = MerkleNode::from(c_cm_base);
         let pos = leaf_position.unwrap();
         for (level, sibling) in c_cm_path.iter().enumerate() {
             let level = level as u8;
-            current = if pos & (1 << level) == 0 {
+            current = if i & (1 << level) == 0 {
                 MerkleNode::combine(level.into(), &current, sibling)
             } else {
                 MerkleNode::combine(level.into(), sibling, &current)
@@ -278,6 +283,7 @@ fn create_leadcoin(
     };
     */
 
+
     let coin_nonce2_msg = [c_seed, c_root_sk.inner(), one.clone(), one.clone()];
     let c_seed2: pallas::Base =
         poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init()
@@ -327,13 +333,11 @@ fn create_coins_election_seeds(
     // mu_rho
     let nonce_mu_msg = [election_seed_nonce, eta, slot];
     let nonce_mu: pallas::Base =
-        poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init()
-            .hash(nonce_mu_msg);
+        poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(nonce_mu_msg);
     // mu_y
     let lead_mu_msg = [election_seed_lead, eta, slot];
     let lead_mu: pallas::Base =
-        poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init()
-            .hash(lead_mu_msg);
+        poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(lead_mu_msg);
     (lead_mu, nonce_mu)
 }
 
@@ -373,12 +377,12 @@ pub fn is_leader(slot: u64, epoch_coins: &Vec<Vec<LeadCoin>>) -> (bool, usize) {
             coin.sigma1.unwrap() * val_base + coin.sigma2.unwrap() * val_base * val_base;
         info!("y: {:?}", y);
         info!("T: {:?}", target_base);
-        if y >= target_base {
-            continue
+        let first_winning = y < target_base;
+        if first_winning && !won {
+            highest_stake_idx = winning_idx;
         }
-
-        won = true;
-        if coin.value.unwrap() > highest_stake {
+        won |= first_winning;
+        if won && coin.value.unwrap() > highest_stake {
             highest_stake = coin.value.unwrap();
             highest_stake_idx = winning_idx;
         }

+ 2 - 3
src/consensus/ouroboros/epoch.rs

@@ -82,10 +82,9 @@ impl Epoch {
     /// * `pk` - proving key
     /// returns  the of proof of the winning coin of slot `sl` at index `idx` with
     /// proving key `pk`
-    pub fn get_proof(&self, sl: u64, idx: usize, pk: &ProvingKey) -> Proof {
+    pub fn get_proof(&self, sl: usize, idx: usize, pk: &ProvingKey) -> Proof {
         info!("get_proof");
-        let competing_coins: &Vec<LeadCoin> = &self.coins.clone()[sl as usize];
-        let coin = competing_coins[idx];
+        let coin = self.get_coin(sl, idx);
         lead_proof::create_lead_proof(pk, coin).unwrap()
     }
 }

+ 1 - 1
src/consensus/ouroboros/stakeholder.rs

@@ -365,7 +365,7 @@ impl Stakeholder {
         info!("Winning coin index: {}", idx);
         // Generating leader proof
         let coin = self.epoch.get_coin(sl as usize, idx);
-        let proof = self.epoch.get_proof(sl, idx, &self.get_leadprovkingkey());
+        let proof = self.epoch.get_proof(sl as usize, idx, &self.get_leadprovkingkey());
         //Verifying generated proof against winning coin public inputs
         info!("Leader proof generated successfully, veryfing...");
         match lead_proof::verify_lead_proof(

+ 8 - 5
src/crypto/leadcoin.rs

@@ -36,7 +36,7 @@ pub struct LeadCoin {
     pub value: Option<u64>,             // coin stake
     pub cm: Option<pallas::Point>,      // coin commitment
     pub cm2: Option<pallas::Point>,     // poured coin commitment
-    pub idx: u32,                       // coin idex
+    pub idx: u32,                       // coin index
     pub sl: Option<pallas::Base>,       // coin slot id
     pub tau: Option<pallas::Base>,      // coin time stamp
     pub nonce: Option<pallas::Base>,    // coin nonce
@@ -73,11 +73,14 @@ impl LeadCoin {
         let po_y_y = *po_y_pt.to_affine().coordinates().unwrap().y();
         let y_coord_arr = [po_y_x, po_y_y];
         let po_y: pallas::Base =
-            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
-                .hash(y_coord_arr);
-        let cm_pos = self.idx;
+            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(y_coord_arr);
         let public_inputs: [pallas::Base; LEAD_PUBLIC_INPUT_LEN] =
-            [po_nonce, *po_pk.x(), *po_pk.y(), po_y];
+            [
+                po_nonce,
+                *po_pk.x(),
+                *po_pk.y(),
+                po_y
+            ];
         public_inputs
     }
 

+ 14 - 3
src/zk/circuit/lead_contract.rs

@@ -669,6 +669,8 @@ impl Circuit<pallas::Base> for LeadContract {
         // Calculate lottery target
         let target =
             arith_chip.add(layouter.namespace(|| "target = term1 + term2"), &term1, &term2)?;
+        let T: Value<pallas::Base> = target.value().cloned();
+        let y: Value<pallas::Base> = y_commit_base.value().cloned();
 
         // Constrain y < target
         lessthan_chip.copy_less_than(
@@ -680,13 +682,21 @@ impl Circuit<pallas::Base> for LeadContract {
         )?;
 
         // Constrain derived `sn_commit` to be equal to witnessed `coin1_serial`.
+
         layouter.assign_region(
-            || "sn_commit equality",
+            || "coin1_cm_root equality",
             |mut region| {
-                region.constrain_equal(sn_commit.cell(), coin1_serial.cell())?;
                 region.constrain_equal(coin1_cm_root.cell(), coin1_commit_root.cell())
             },
-        );
+        )?;
+
+        layouter.assign_region(
+            || "sn_commit equality",
+            |mut region| {
+                region.constrain_equal(sn_commit.cell(), coin1_serial.cell())
+            },
+        )?;
+
 
         // Constrain equality between witnessed and derived commitment
         coin2_commitment
@@ -719,6 +729,7 @@ impl Circuit<pallas::Base> for LeadContract {
             config.primary,
             LEADCOIN_Y_BASE_OFFSET,
         )?;
+
         Ok(())
     }
 }