ghassmo 3 лет назад
Родитель
Сommit
e5e09726b9
4 измененных файлов с 90 добавлено и 90 удалено
  1. 6 9
      example/lead.rs
  2. 52 50
      src/blockchain/epoch.rs
  3. 1 1
      src/crypto/leadcoin.rs
  4. 31 30
      src/stakeholder/stakeholder.rs

+ 6 - 9
example/lead.rs

@@ -1,15 +1,12 @@
+use env_logger;
 use futures::executor::block_on;
 use halo2_proofs::dev::MockProver;
+use log::{debug, error, info, log_enabled, Level};
 use pasta_curves::pallas;
 use url::Url;
-use log::{debug, error, log_enabled, info, Level};
-use env_logger;
 
 use darkfi::{
-    blockchain::{
-        epoch::{Epoch},
-        EpochConsensus,
-    },
+    blockchain::{epoch::Epoch, EpochConsensus},
     crypto::leadcoin::{LeadCoin, LEAD_PUBLIC_INPUT_LEN},
     net::Settings,
     stakeholder::stakeholder::Stakeholder,
@@ -23,7 +20,7 @@ fn main() {
 
     //
     const LEN: usize = 10;
-    let value = 33223;  //static stake value
+    let value = 33223; //static stake value
 
     //
     let settings = Settings {
@@ -49,10 +46,10 @@ fn main() {
         block_on(Stakeholder::new(consensus, settings, "db", 0, Some(k))).unwrap();
 
     let eta: pallas::Base = stakeholder.get_eta();
-    let mut epoch = Epoch::new(consensus,  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, vec![]);
     let coin = coins[0][0];
     let contract = coin.create_contract();
 

+ 52 - 50
src/blockchain/epoch.rs

@@ -13,6 +13,7 @@ use pasta_curves::{
 use rand::{thread_rng, Rng};
 
 use crate::crypto::{
+    coin::OwnCoin,
     constants::MERKLE_DEPTH_ORCHARD,
     lead_proof,
     leadcoin::LeadCoin,
@@ -20,7 +21,6 @@ use crate::crypto::{
     proof::{Proof, ProvingKey},
     types::DrkValueBlind,
     util::{mod_r_p, pedersen_commitment_base, pedersen_commitment_u64},
-    coin::OwnCoin,
 };
 
 const PRF_NULLIFIER_PREFIX: u64 = 0;
@@ -79,20 +79,15 @@ impl EpochConsensus {
 pub struct Epoch {
     pub consensus: EpochConsensus,
     // should have ep, slot, current block, etc.
-    pub eta: pallas::Base,    // CRS for the leader selection.
+    pub eta: pallas::Base,     // CRS for the leader selection.
     coins: Vec<Vec<LeadCoin>>, // competing coins
 }
 
 impl Epoch {
     pub fn new(consensus: EpochConsensus, true_random: pallas::Base) -> Self {
-        Self {
-            consensus: consensus,
-            eta: true_random,
-            coins: vec![],
-        }
+        Self { consensus, eta: true_random, coins: vec![] }
     }
 
-
     /// retrive leadership lottary coins of static stake,
     /// retrived for for commitment in the genesis data
     pub fn get_coins(&self) -> Vec<Vec<LeadCoin>> {
@@ -103,12 +98,12 @@ impl Epoch {
         self.coins[sl][idx]
     }
 
-    pub fn len(&self)  -> usize {
+    pub fn len(&self) -> usize {
         self.consensus.get_epoch_len() as usize
     }
 
     pub fn col(&self) -> usize {
-        if self.coins.len()==0 {
+        if self.coins.len() == 0 {
             0
         } else {
             self.coins[0].len()
@@ -116,7 +111,7 @@ impl Epoch {
     }
 
     //
-    fn create_coins_election_seeds(&self,  sl: pallas::Base) -> (pallas::Base, pallas::Base) {
+    fn create_coins_election_seeds(&self, sl: pallas::Base) -> (pallas::Base, pallas::Base) {
         let election_seed_nonce: pallas::Base = pallas::Base::from(3);
         let election_seed_lead: pallas::Base = pallas::Base::from(22);
 
@@ -144,7 +139,7 @@ impl Epoch {
         let mut root_sks: Vec<MerkleNode> = vec![];
         let mut path_sks: Vec<[MerkleNode; MERKLE_DEPTH_ORCHARD]> = vec![];
         let mut prev_sk_base: pallas::Base = pallas::Base::one();
-        for _i in 0..self.len(){
+        for _i in 0..self.len() {
             //TODO (fix) add sk for the coin struct to be used in txs decryption of tx notes.
             let sk_bytes = if _i == 0 {
                 let base = pedersen_commitment_u64(1, pallas::Scalar::random(&mut rng));
@@ -175,7 +170,7 @@ impl Epoch {
         (root_sks, path_sks)
     }
     //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, sigma: 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() {
@@ -188,10 +183,17 @@ impl Epoch {
         let mut coins: Vec<Vec<LeadCoin>> = vec![];
         for i in 0..self.len() {
             // if you have any stake used is for competition
-            if owned.len()>0 {
+            if owned.len() > 0 {
                 let mut slot_coins = vec![];
-                for j in  0..owned.len() {
-                    let coin = self.create_leadcoin(sigma, owned[j].note.value, i, root_sks[i], path_sks[i], seeds[i]);
+                for j in 0..owned.len() {
+                    let coin = self.create_leadcoin(
+                        sigma,
+                        owned[j].note.value,
+                        i,
+                        root_sks[i],
+                        path_sks[i],
+                        seeds[i],
+                    );
                     slot_coins.push(coin.clone());
                 }
                 self.coins.push(slot_coins);
@@ -199,18 +201,21 @@ impl Epoch {
             // otherwise compete with zero stake
             else {
                 let coin = self.create_leadcoin(sigma, 0, i, root_sks[i], path_sks[i], seeds[i]);
-                self.coins.push(vec!(coin));
+                self.coins.push(vec![coin]);
             }
         }
         self.coins.clone()
     }
 
-    pub fn create_leadcoin(&self, sigma: pallas::Base,
-                           value : u64,
-                           i: usize,
-                           c_root_sk: MerkleNode,
-                           c_path_sk: [MerkleNode; MERKLE_DEPTH_ORCHARD],
-                           seed: u64) -> LeadCoin {
+    pub fn create_leadcoin(
+        &self,
+        sigma: pallas::Base,
+        value: u64,
+        i: usize,
+        c_root_sk: MerkleNode,
+        c_path_sk: [MerkleNode; MERKLE_DEPTH_ORCHARD],
+        seed: u64,
+    ) -> LeadCoin {
         //random commitment blinding values
         let mut rng = thread_rng();
         let c_cm1_blind: DrkValueBlind = pallas::Scalar::random(&mut rng);
@@ -227,19 +232,18 @@ impl Epoch {
         let coin_pk_msg = [c_tau, c_root_sk.inner()];
         let c_pk: pallas::Base =
             poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
-            .hash(coin_pk_msg);
+                .hash(coin_pk_msg);
 
         let c_seed = pallas::Base::from(seed);
         let sn_msg = [c_seed, c_root_sk.inner()];
         let c_sn: pallas::Base =
             poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
-            .hash(sn_msg);
+                .hash(sn_msg);
 
-        let coin_commit_msg_input =
-            [pallas::Base::from(PRF_NULLIFIER_PREFIX), c_pk, c_v, c_seed];
+        let coin_commit_msg_input = [pallas::Base::from(PRF_NULLIFIER_PREFIX), c_pk, c_v, c_seed];
         let coin_commit_msg: pallas::Base =
             poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init()
-            .hash(coin_commit_msg_input);
+                .hash(coin_commit_msg_input);
         let c_cm: pallas::Point = pedersen_commitment_base(coin_commit_msg, c_cm1_blind);
         let c_cm_coordinates = c_cm.to_affine().coordinates().unwrap();
         let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
@@ -247,21 +251,17 @@ impl Epoch {
         tree_cm.append(&c_cm_node.clone());
         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_cm_path = tree_cm.authentication_path(leaf_position.unwrap(), &c_root_cm).unwrap();
 
         let coin_nonce2_msg = [c_seed, c_root_sk.inner()];
         let c_seed2: pallas::Base =
-            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
-            )
-            .hash(coin_nonce2_msg);
+            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
+                .hash(coin_nonce2_msg);
 
-        let coin2_commit_msg_input =
-            [pallas::Base::from(PRF_NULLIFIER_PREFIX), c_pk, c_v, c_seed2];
+        let coin2_commit_msg_input = [pallas::Base::from(PRF_NULLIFIER_PREFIX), c_pk, c_v, c_seed2];
         let coin2_commit_msg: pallas::Base =
-            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init(
-            )
-            .hash(coin2_commit_msg_input);
+            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init()
+                .hash(coin2_commit_msg_input);
         let c_cm2 = pedersen_commitment_base(coin2_commit_msg, c_cm2_blind);
 
         // election seeds
@@ -297,30 +297,32 @@ impl Epoch {
     /// * `sl` - slot relative index
     /// * `idx` - index of the winning coin
     /// returns true if the stakeholder is a leader for the current slot, else otherwise
-    pub fn is_leader(&self, sl: u64, idx:  &mut usize) -> bool {
+    pub fn is_leader(&self, sl: u64, idx: &mut usize) -> bool {
         let slusize = sl as usize;
         debug!("slot: {}, coin len: {}", sl, self.coins.len());
         assert!(slusize < self.coins.len());
-        let competing_coins : &Vec<LeadCoin>= &self.coins.clone()[sl as usize];
+        let competing_coins: &Vec<LeadCoin> = &self.coins.clone()[sl as usize];
         let mut am_leader = vec![];
         let mut highest_stake = 0;
-        let mut highest_stake_idx : usize= 0;
+        let mut highest_stake_idx: usize = 0;
         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()
+                poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+                )
                 .hash(y_exp);
             // 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 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;
+            let iam_leader = target < y_x;
             if iam_leader && coin.value.unwrap() > highest_stake {
                 highest_stake = coin.value.unwrap();
                 highest_stake_idx = winning_idx;
@@ -336,8 +338,8 @@ 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 {
-        let competing_coins : &Vec<LeadCoin> = &self.coins.clone()[sl as usize];
+    pub fn get_proof(&self, sl: u64, idx: usize, pk: &ProvingKey) -> Proof {
+        let competing_coins: &Vec<LeadCoin> = &self.coins.clone()[sl as usize];
         let coin = competing_coins[idx];
         lead_proof::create_lead_proof(pk, coin).unwrap()
     }

+ 1 - 1
src/crypto/leadcoin.rs

@@ -21,7 +21,7 @@ pub const LEAD_PUBLIC_INPUT_LEN: usize = 10;
 
 #[derive(Debug, Default, Clone, Copy)]
 pub struct LeadCoin {
-    pub value: Option<u64>,                         // coin stake
+    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

+ 31 - 30
src/stakeholder/stakeholder.rs

@@ -1,13 +1,13 @@
 use async_executor::Executor;
 use async_std::sync::Arc;
+use halo2_proofs::arithmetic::Field;
 use log::{debug, error, info};
 use std::fmt;
-use halo2_proofs::arithmetic::Field;
 
 use rand::rngs::OsRng;
 use std::{thread, time::Duration};
 
-use crate::zk::circuit::{LeadContract,BurnContract,MintContract};
+use crate::zk::circuit::{BurnContract, LeadContract, MintContract};
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 
 use crate::{
@@ -17,24 +17,26 @@ use crate::{
         TransactionLeadProof,
     },
     crypto::{
-        constants::MERKLE_DEPTH,
         address::Address,
+        coin::OwnCoin,
+        constants::MERKLE_DEPTH,
         keypair::{Keypair, PublicKey, SecretKey},
-        nullifier::Nullifier,
         leadcoin::LeadCoin,
         merkle_node::MerkleNode,
+        note::{EncryptedNote, Note},
+        nullifier::Nullifier,
         proof::{Proof, ProvingKey, VerifyingKey},
         schnorr::{SchnorrPublic, SchnorrSecret, Signature},
-        coin::OwnCoin,
-        note::{EncryptedNote, Note},
     },
+    net::{MessageSubscription, P2p, Settings, SettingsPtr},
     node::state::{state_transition, ProgramState, StateUpdate},
-    tx::builder::{
-        TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
-        TransactionBuilderOutputInfo,
+    tx::{
+        builder::{
+            TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
+            TransactionBuilderOutputInfo,
+        },
+        Transaction,
     },
-    net::{MessageSubscription, P2p, Settings, SettingsPtr},
-    tx::Transaction,
     util::{
         clock::{Clock, Ticks},
         path::expand_path,
@@ -58,7 +60,8 @@ pub struct SlotWorkspace {
     pub e: u64,                // epoch index
     pub sl: u64,               // relative slot index
     pub txs: Vec<Transaction>, // unpublished block transactions
-    pub root: MerkleNode, /// merkle root of txs
+    pub root: MerkleNode,
+    /// merkle root of txs
     pub m: StakeholderMetadata,
     pub om: OuroborosMetadata,
     pub is_leader: bool,
@@ -127,7 +130,6 @@ impl SlotWorkspace {
     pub fn set_leader(&mut self, alead: bool) {
         self.is_leader = alead;
     }
-
 }
 
 struct StakeholderState {
@@ -224,7 +226,6 @@ impl StakeholderState {
     }
 }
 
-
 pub struct Stakeholder {
     pub blockchain: Blockchain, // stakeholder view of the blockchain
     pub net: Arc<P2p>,
@@ -242,10 +243,10 @@ pub struct Stakeholder {
     pub workspace: SlotWorkspace,
     pub id: i64,
     pub keypair: Keypair,
-    pub cashier_signature_public : PublicKey,
-    pub faucet_signature_public : PublicKey,
-    pub cashier_signature_secret : SecretKey,
-    pub faucet_signature_secret : SecretKey,
+    pub cashier_signature_public: PublicKey,
+    pub faucet_signature_public: PublicKey,
+    pub cashier_signature_secret: SecretKey,
+    pub faucet_signature_secret: SecretKey,
     //pub subscription: Subscription<Result<ChannelPtr>>,
     //pub chanptr : ChannelPtr,
     //pub msgsub : MessageSubscription::<BlockInfo>,
@@ -289,19 +290,19 @@ impl Stakeholder {
 
         let keypair = Keypair::random(&mut OsRng);
         debug!(target: LOG_T, "stakeholder constructed");
-        Ok( Self {
+        Ok(Self {
             blockchain: bc,
             net: p2p,
             clock,
             ownedcoins: vec![], //TODO should be read from wallet db.
             epoch,
             epoch_consensus: consensus,
-            lead_pk: lead_pk,
-            mint_pk: mint_pk,
-            burn_pk: burn_pk,
-            lead_vk: lead_vk,
-            mint_vk: mint_vk,
-            burn_vk: burn_vk,
+            lead_pk,
+            mint_pk,
+            burn_pk,
+            lead_vk,
+            mint_vk,
+            burn_vk,
             playing: true,
             workspace,
             id,
@@ -531,10 +532,10 @@ impl Stakeholder {
         self.workspace.set_sl(sl);
         self.workspace.set_e(e);
         self.workspace.set_st(st);
-        let mut winning_coin_idx :  usize = 0;
+        let mut winning_coin_idx: usize = 0;
         let won = self.epoch.is_leader(sl, &mut winning_coin_idx);
         let proof = if won {
-            self.epoch.get_proof(sl, winning_coin_idx,  &self.get_leadprovkingkey())
+            self.epoch.get_proof(sl, winning_coin_idx, &self.get_leadprovkingkey())
         } else {
             Proof::new(vec![])
         };
@@ -552,14 +553,14 @@ impl Stakeholder {
         if won {
             //TODO (res) verify the coin is finalized
             // could be finalized in later slot accord to the finalization policy that is WIP.
-            let owned_coin = self.finalize_coin(&self.epoch.get_coin(sl as usize, winning_coin_idx as usize));
+            let owned_coin =
+                self.finalize_coin(&self.epoch.get_coin(sl as usize, winning_coin_idx as usize));
             self.ownedcoins.push(owned_coin);
         }
     }
 
     //TODO (res) validate the owncoin is the same winning leadcoin
-    pub fn finalize_coin (&self, coin : &LeadCoin) -> OwnCoin {
-
+    pub fn finalize_coin(&self, coin: &LeadCoin) -> OwnCoin {
         let mut state = StakeholderState {
             tree: BridgeTree::<MerkleNode, MERKLE_DEPTH>::new(TREE_LEN),
             merkle_roots: vec![],