Explorar o código

finalize stake/unstake contracts

mohab metwally %!s(int64=3) %!d(string=hai) anos
pai
achega
1480375c52

+ 8 - 8
src/consensus/leadcoin.rs

@@ -110,8 +110,8 @@ impl LeadCoin {
         coin1_sk_pos: usize,
         // Merkle path to the secret key of `coin_1` in the Merkle tree of secret keys
         coin1_sk_merkle_path: [MerkleNode; MERKLE_DEPTH_LEADCOIN],
-        // what's seed supposed to be?
-        seed: u64,
+        // coin1 nonce
+        seed: pallas::Base,
         // Merkle tree of coin commitments
         coin_commitment_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
     ) -> Self {
@@ -123,10 +123,10 @@ impl LeadCoin {
         // pk
         let pk = Self::util_pk(coin1_sk_root, tau);
         // Derive the nonce for coin2
-        let coin2_seed = Self::util_derived_rho(coin1_sk_root, pallas::Base::from(seed));
+        let coin2_seed = Self::util_derived_rho(coin1_sk_root, seed);
         info!("coin2_seed[{}]: {:?}", slot_index, coin2_seed);
         let coin1_commitment =
-            Self::commitment(pk, pallas::Base::from(value), pallas::Base::from(seed), coin1_blind);
+            Self::commitment(pk, pallas::Base::from(value), seed, coin1_blind);
         // Hash its coordinates to get a base field element
         let c1_cm_coords = coin1_commitment.to_affine().coordinates().unwrap();
         let c1_base_msg = [*c1_cm_coords.x(), *c1_cm_coords.y()];
@@ -151,7 +151,7 @@ impl LeadCoin {
             value,
             // Assume tau is sl for simplicity
             tau,
-            nonce: pallas::Base::from(seed),
+            nonce: seed,
             coin1_commitment,
             coin2_commitment,
             coin1_commitment_root,
@@ -355,9 +355,9 @@ impl LeadCoin {
         let zkbin = ZkBinary::decode(bincode).unwrap();
         let witnesses = vec![
             Witness::MerklePath(Value::known(self.coin1_commitment_merkle_path)),
-            Witness::Uint32(Value::known(self.idx)),
+            Witness::Uint32(Value::known(self.coin1_commitment_pos)),
             Witness::Uint32(Value::known(self.coin1_sk_pos)),
-            Witness::Base(Value::known(self.coin1_sk.inner())),
+            Witness::Base(Value::known(self.coin1_sk)),
             Witness::Base(Value::known(self.coin1_sk_root.inner())),
             Witness::MerklePath(Value::known(self.coin1_sk_merkle_path)),
             Witness::Base(Value::known(self.tau)),
@@ -391,7 +391,7 @@ impl LeadCoin {
         let zkbin = ZkBinary::decode(bincode)?;
         let retval = pallas::Base::from(change_coin.value);
         let xferval = pallas::Base::from(transfered_coin.value);
-        let pos: u32 = self.idx;
+        let pos: u32 = self.coin1_commitment_pos;
         let value = pallas::Base::from(self.value);
         let witnesses = vec![
             // coin (1) burned coin

+ 3 - 2
src/consensus/state.rs

@@ -293,7 +293,7 @@ impl ConsensusState {
             epoch_secrets.merkle_roots[0],
             0,
             epoch_secrets.merkle_paths[0],
-            seeds[0],
+            pallas::Base::from(seeds[0]),
             &mut self.coins_tree,
         );
         coins.push(coin);
@@ -435,7 +435,8 @@ impl ConsensusState {
     }
 
     fn weighted_f_int(&self) -> Float10 {
-        constants::KI.clone() * self.f_int()
+        //constants::KI.clone() * self.f_int()
+        self.tuned_ki() * self.f_int()
     }
 
     fn zero_leads_len(&self) -> Float10 {

+ 5 - 4
src/consensus/validator.rs

@@ -27,6 +27,7 @@ use darkfi_sdk::{
         schnorr::{SchnorrPublic, SchnorrSecret},
         MerkleNode,
         PublicKey,
+        SecretKey,
     },
     db::SMART_CONTRACT_ZKAS_DB_NAME,
     incrementalmerkletree::{bridgetree::BridgeTree, Tree},
@@ -292,7 +293,7 @@ impl ValidatorState {
             coin.create_lead_proof(sigma1, sigma2, self.lead_proving_key.as_ref().unwrap());
 
         // Signing using coin
-        let secret_key = coin.secret_key;
+        let secret_key = coin.coin1_sk;
         let header = Header::new(
             prev_hash,
             self.consensus.slot_epoch(slot),
@@ -300,14 +301,14 @@ impl ValidatorState {
             Timestamp::current_time(),
             root,
         );
-        let signed_proposal = secret_key.sign(&mut OsRng, &header.headerhash().as_bytes()[..]);
-        let public_key = PublicKey::from_secret(secret_key);
+        let signed_proposal = SecretKey::from(secret_key).sign(&mut OsRng, &header.headerhash().as_bytes()[..]);
+        let public_key = PublicKey::from_secret(secret_key.into());
 
         let lead_info = LeadInfo::new(
             signed_proposal,
             public_key,
             public_inputs,
-            coin.slot,
+            slot,
             coin.eta,
             LeadProof::from(proof?),
             self.consensus.get_current_offset(slot),

+ 78 - 57
src/contract/money/src/client.rs

@@ -33,6 +33,7 @@ use darkfi::{
         vm_stack::Witness,
     },
     zkas::ZkBinary,
+    consensus::leadcoin::LeadCoin,
     ClientFailed, Error, Result,
 };
 use darkfi_sdk::{
@@ -55,7 +56,7 @@ use halo2_proofs::{arithmetic::Field, circuit::Value};
 use log::{debug, error, info};
 use rand::rngs::OsRng;
 
-use crate::state::{ClearInput, Input, MoneyTransferParams, Output};
+use crate::state::{ClearInput, Input, MoneyTransferParams, MoneyStakeParams,  MoneyUnstakeParams, Output, StakedOutput, StakedInput,};
 
 // Wallet SQL table constant names. These have to represent the SQL schema.
 // TODO: They should also ideally be prefixed with the contract ID to avoid
@@ -494,16 +495,20 @@ impl StakeLeadMintRevealed {
         let value_commit = pedersen_commitment_base(value, value_blind);
         let coord = commitment.to_affine().coordinates().unwrap();
         Self {
-            value_commit,
-            pk,
-            *coord.x(),
-            *coord.y(),
+            value_commit: value_commit,
+            pk: pk,
+            commitment_x: *coord.x(),
+            commitment_y: *coord.y(),
         }
 
     }
     pub fn to_vec(&self) -> Vec<pallas::Base> {
+        let value_coord = self.value_commit.to_affine().coordinates().unwrap();
+        let value_cm_x = *value_coord.x();
+        let value_cm_y = *value_coord.y();
         vec![
-            self.value_commit,
+            value_cm_x,
+            value_cm_y,
             self.pk,
             self.commitment_x,
             self.commitment_y,
@@ -518,15 +523,16 @@ fn create_stake_mint_proof(
     coin_commitment: pallas::Point,
     value: pallas::Base,
     value_blind: ValueBlind,
-    coin_blind: pallas::Base,
+    coin_blind: ValueBlind,
     sk: pallas::Base,
     sk_root: pallas::Base,
     tau: pallas::Base,
     nonce: pallas::Base, // rho
-) > Result<(Proof, StakeLeadMintRevealed)> {
+) -> Result<(Proof, StakeLeadMintRevealed)> {
     let revealed = StakeLeadMintRevealed::compute(
         value,
         public_key,
+        value_blind,
         coin_commitment,
     );
 
@@ -558,6 +564,7 @@ struct UnstakeLeadBurnRevealed {
 impl UnstakeLeadBurnRevealed {
     pub fn compute(
         value: pallas::Base,
+        value_blind: ValueBlind,
         pk: pallas::Base,
         commitment: pallas::Point,
         commitment_root: pallas::Base,
@@ -566,6 +573,8 @@ impl UnstakeLeadBurnRevealed {
     ) -> Self {
         let value_commit = pedersen_commitment_base(value, value_blind);
         let coord = commitment.to_affine().coordinates().unwrap();
+        let commitment_x = *coord.x();
+        let commitment_y = *coord.y();
         Self {
             value_commit,
             pk,
@@ -578,8 +587,12 @@ impl UnstakeLeadBurnRevealed {
     }
 
     pub fn to_vec(&self) -> Vec<pallas::Base> {
+        let coord = self.value_commit.to_affine().coordinates().unwrap();
+        let value_cm_x = *coord.x();
+        let value_cm_y = *coord.y();
         vec![
-            self.value_commit,
+            value_cm_x,
+            value_cm_y,
             self.pk,
             self.commitment_x,
             self.commitment_y,
@@ -595,8 +608,9 @@ fn create_unstake_burn_proof(
     pk: &ProvingKey,
     value: pallas::Base,
     value_blind: ValueBlind,
-    coin_blind: pallas::Base,
+    coin_blind: ValueBlind,
     public_key: pallas::Base,
+    sk: pallas::Base,
     sk_root: pallas::Base,
     sk_pos: incrementalmerkletree::Position,
     sk_path: Vec<MerkleNode>,
@@ -608,8 +622,9 @@ fn create_unstake_burn_proof(
     nonce: pallas::Base,
     nullifier: pallas::Base,
 ) -> Result<(Proof, UnstakeLeadBurnRevealed)> {
-    let revealed = UnstakeLeadMintRevealed::compute(
+    let revealed = UnstakeLeadBurnRevealed::compute(
         value,
+        value_blind,
         public_key,
         commitment,
         commitment_root,
@@ -1059,16 +1074,16 @@ pub fn build_transfer_tx(
 }
 
 pub fn build_stake_tx(
-    pubkey: &PublicKey,
+    //pubkey: &PublicKey,
     coins: &[OwnCoin],
-    tx_tree: &BridgeTree<MerkleNode, MERKLE_DEPTH>,
-    cm_tree: &BridgeTree<MerkleNode, MERKLE_DEPTH>,
-    sk_tree: &BridgeTree<MerkleNode, MERKLE_DEPTH>,
+    tx_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
+    cm_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
+    sk_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
     mint_zkbin: &ZkBinary,
     mint_pk: &ProvingKey,
     burn_zkbin: &ZkBinary,
     burn_pk: &ProvingKey,
-    slot_index: pallas::Base,
+    slot_index: u64,
     eta: pallas::Base,
 ) -> Result<(
     MoneyStakeParams,
@@ -1078,8 +1093,8 @@ pub fn build_stake_tx(
     Vec<ValueBlind>,
 )> {
     // convert owncoins to leadcoins.
-    let token_blind = ValueBlind::random(&mut OsRng);
-    let leadcoins : Vec<LeadCoin>= vec![];
+    //let token_blind = ValueBlind::random(&mut OsRng);
+    let mut leadcoins : Vec<LeadCoin>= vec![];
     let mut params = MoneyStakeParams {
         inputs: vec![],
         outputs: vec![],
@@ -1110,6 +1125,7 @@ pub fn build_stake_tx(
             spend_hook,
             user_data,
             user_data_blind,
+            coin.note.coin_blind,
             coin.secret,
             coin.leaf_position,
             tx_merkle_path.clone(),
@@ -1127,7 +1143,7 @@ pub fn build_stake_tx(
         proofs.push(own_proof);
         let lead_value_blind = ValueBlind::random(&mut OsRng);
         lead_blinds.push(lead_value_blind);
-        sk_tree.append(&MerkleNode::from(coin.secret));
+        sk_tree.append(&MerkleNode::from(coin.secret.inner()));
         let sk_pos = sk_tree.witness().unwrap();
         let sk_root = sk_tree.root(0).unwrap();
         let sk_merkle_path = sk_tree.authentication_path(sk_pos, &sk_root).unwrap();
@@ -1135,10 +1151,11 @@ pub fn build_stake_tx(
             eta, // randomness from last finalized block.
             coin.note.value,
             slot_index, // tau
-            coin.secret, // coin secret key
+            coin.secret.inner(), // coin secret key
             sk_root,
-            sk_pos,
-            sk_merkle_path,
+            sk_pos.try_into().unwrap(),
+            sk_merkle_path.try_into().unwrap(),
+            coin.note.serial,
             cm_tree,
         );
         leadcoins.push(leadcoin);
@@ -1149,23 +1166,23 @@ pub fn build_stake_tx(
             mint_pk,
             public_key,
             leadcoin.coin1_commitment,
-            coin.note.value,
+            pallas::Base::from(coin.note.value),
             lead_value_blind,
             lead_coin_blind,
-            coin.secret,
-            sk_root,
-            slot_index, // tau
+            coin.secret.inner(),
+            sk_root.inner(),
+            pallas::Base::from(slot_index), // tau
             coin.note.serial, // nonce
         )?;
         let coin_commit_coords = [
             lead_revealed.commitment_x,
             lead_revealed.commitment_y,
         ];
-        let coin_commit_hash = poseidon_hash(coords);
-        params.outputs.push(StakedOutput{
-            lead_revealed.value_commit,
-            coin_commit_hash,
-            public_key,
+        let coin_commit_hash = poseidon_hash(coin_commit_coords);
+        params.outputs.push(StakedOutput {
+            value_commit: lead_revealed.value_commit,
+            coin_commit_hash: coin_commit_hash,
+            coin_pk_hash: public_key,
         });
         proofs.push(lead_proof);
     }
@@ -1181,15 +1198,15 @@ pub fn build_unstake_tx(
     burn_zkbin: &ZkBinary, // unstake lead burn binary
     burn_pk: &ProvingKey,
 ) -> Result<(
-    MoneyUnStakeParams,
+    MoneyUnstakeParams,
     Vec<Proof>,
     Vec<SecretKey>,
     Vec<ValueBlind>,
     Vec<ValueBlind>,
 )> {
     // convert leadcoin to owncoin
-    let token_blind = ValueBlind::random(&mut OsRng);
-    let owncoins : Vec<OwnCoin>= vec![];
+    //let token_blind = ValueBlind::random(&mut OsRng);
+    //let owncoins : Vec<OwnCoin>= vec![];
     let mut params = MoneyUnstakeParams {
         inputs: vec![],
         outputs: vec![],
@@ -1201,33 +1218,38 @@ pub fn build_unstake_tx(
         // burn lead coin
         let value_blind = ValueBlind::random(&mut OsRng);
         lead_blinds.push(value_blind);
+        let pk = coin.pk();
+        let nullifier = coin.sn();
         let (unstake_proof, unstake_revealed) = create_unstake_burn_proof(
             burn_zkbin,
             burn_pk,
-            coin.value,
+            pallas::Base::from(coin.value),
             value_blind,
             coin.coin1_blind,
-            coin.pk(),
-            coin.coin1_sk_root,
-            coin.coin1_sk_pos,
-            coin.coin1_sk_merkle_path,
-            coin.coin1_commitment_merkle_path,
+            pk,
+            coin.coin1_sk,
+            coin.coin1_sk_root.inner(),
+            incrementalmerkletree::Position::from(coin.coin1_sk_pos as usize),
+            coin.coin1_sk_merkle_path.to_vec(),
+            coin.coin1_commitment_merkle_path.to_vec(),
             coin.coin1_commitment,
-            coin.coin1_commitment_root,
-            coin.coin1_commitment_pos,
+            coin.coin1_commitment_root.inner(),
+            incrementalmerkletree::Position::from(coin.coin1_commitment_pos as usize),
             coin.tau,
             coin.nonce,
-            coin.sn(),
-        );
+            nullifier,
+        )?;
+        let commitment_coord = [unstake_revealed.commitment_x,
+                                unstake_revealed.commitment_y
+        ];
+        let coin_commitment_hash = poseidon_hash(commitment_coord);
         params.inputs.push(StakedInput{
-            coin.sn(),
-            unstake_revealed.value_commit,
-            poseidon_hash([unstake_revealed.commitment_x,
-                           unstake_revealed.commitment_y
-            ]),
-            unstake_revealed.pk,
-            unstake_revealed.commitment_root,
-            unstake_revealed.sk_root,
+            nullifier: nullifier.into(),
+            value_commit: unstake_revealed.value_commit,
+            coin_commit_hash: coin_commitment_hash,
+            coin_pk_hash: unstake_revealed.pk,
+            coin_commit_root: unstake_revealed.commitment_root.into(),
+            sk_root: unstake_revealed.sk_root.into(),
         });
         proofs.push(unstake_proof);
         let own_value_blind = ValueBlind::random(&mut OsRng);
@@ -1244,13 +1266,13 @@ pub fn build_unstake_tx(
             mint_pk,
             coin.value,
             token_id_recv,
-            value_recv_blind,
+            own_value_blind,
             token_recv_blind,
             serial,
             spend_hook,
             user_data,
             coin_blind,
-            pubkey, //receipient public_key
+            *pubkey, //receipient public_key
         )?;
         proofs.push(proof);
         // Encrypted note
@@ -1265,7 +1287,7 @@ pub fn build_unstake_tx(
             memo: vec![],
         };
 
-        let encrypted_note = note.encrypt(&output.public_key)?;
+        let encrypted_note = note.encrypt(&pubkey)?;
 
         params.outputs.push(Output {
             value_commit: revealed.value_commit,
@@ -1274,9 +1296,8 @@ pub fn build_unstake_tx(
             ciphertext: encrypted_note.ciphertext,
             ephem_public: encrypted_note.ephem_public,
         });
-
-        Ok((params, proofs, vec![], lead_blinds, own_blinds))
     }
+    Ok((params, proofs, vec![], lead_blinds, own_blinds))
 }
 
 fn compute_remainder_blind(

+ 12 - 11
src/contract/money/src/lib.rs

@@ -69,7 +69,7 @@ impl TryFrom<u8> for MoneyFunction {
 pub mod state;
 
 #[cfg(not(feature = "no-entrypoint"))]
-use state::{MoneyTransferParams, MoneyTransferUpdate};
+use state::{MoneyTransferParams, MoneyTransferUpdate, MoneyStakeParams, MoneyUnstakeParams, MoneyStakeUpdate};
 
 #[cfg(feature = "client")]
 /// Transaction building API for clients interacting with this contract.
@@ -88,9 +88,14 @@ pub const MONEY_CONTRACT_COIN_ROOTS_TREE: &str = "coin_roots";
 pub const MONEY_CONTRACT_NULLIFIERS_TREE: &str = "nullifiers";
 pub const MONEY_CONTRACT_FIXED_SUPPLY_TREE: &str = "fixed_supply_tokens";
 pub const MONEY_CONTRACT_INFO_TREE: &str = "info";
+// lead coin, nullifier sled trees.
+pub const MONEY_CONTRACT_LEAD_COIN_ROOTS_TREE: &str = "lead_coin_roots";
+pub const MONEY_CONTRACT_LEAD_NULLIFIERS_TREE: &str = "lead_nullifiers";
+pub const MONEY_CONTRACT_LEAD_INFO_TREE: &str = "lead_info";
 
 // This is a key inside the info tree
 pub const MONEY_CONTRACT_COIN_MERKLE_TREE: &str = "coin_tree";
+pub const MONEY_CONTRACT_LEAD_COIN_MERKLE_TREE: &str = "lead_coin_tree";
 pub const MONEY_CONTRACT_FAUCET_PUBKEYS: &str = "faucet_pubkeys";
 
 /// zkas mint contract namespace
@@ -306,7 +311,7 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
                         *value_coords.x(),
                         *value_coords.y(),
                         output.coin_pk_hash,
-                        output.coin,
+                        output.coin_commit_hash,
                     ],
                 ));
             }
@@ -324,7 +329,6 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
             let params: MoneyUnstakeParams = deserialize(&self_.data[1..])?;
 
             let mut zk_public_values: Vec<(String, Vec<pallas::Base>)> = vec![];
-            let mut signature_pubkeys: Vec<PublicKey> = vec![];
 
             for input in &params.inputs {
                 let value_coords = input.value_commit.to_affine().coordinates().unwrap();
@@ -335,8 +339,8 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
                         *value_coords.y(),
                         input.coin_pk_hash,
                         input.coin_commit_hash,
-                        input.coin_commit_root,
-                        input.sk_root,
+                        input.coin_commit_root.inner(),
+                        input.sk_root.inner(),
                         input.nullifier.inner(),
                     ],
                 ));
@@ -359,7 +363,6 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
             }
             let mut metadata = vec![];
             zk_public_values.encode(&mut metadata)?;
-            signature_pubkeys.encode(&mut metadata)?;
 
             // Using this, we pass the above data to the host.
             set_return_data(&metadata)?;
@@ -574,7 +577,6 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
 
             assert!(params.inputs.len() == params.outputs.len());
 
-            let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
             let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_LEAD_NULLIFIERS_TREE)?;
             let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_LEAD_COIN_ROOTS_TREE)?;
 
@@ -614,7 +616,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
                     msg!("[Stake] Error: Duplicate coin found in output {}", i);
                     return Err(ContractError::Custom(23))
                 }
-                new_coins.push(Coin::from(output.coin));
+                new_coins.push(Coin::from(output.coin_commit_hash));
                 valcom_total -= output.value_commit;
             }
 
@@ -641,10 +643,9 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
 
             assert!(params.inputs.len() == params.outputs.len());
 
-            let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
             let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_LEAD_NULLIFIERS_TREE)?;
             let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_LEAD_COIN_ROOTS_TREE)?;
-            let sk_roots_db = db_lookup(cid, MONEY_CONTRACT_LEAD_SK_ROOTS_TREE)?;
+            //let sk_roots_db = db_lookup(cid, MONEY_CONTRACT_LEAD_SK_ROOTS_TREE)?;
 
             // Accumulator for the value commitments
             let mut valcom_total = pallas::Point::identity();
@@ -701,7 +702,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
             }
 
             // Create a state update
-            let update = MoneyUnstakeUpdate { nullifiers: new_nullifiers, coins: new_coins  };
+            let update = MoneyStakeUpdate { nullifiers: new_nullifiers, coins: new_coins  };
             let mut update_data = vec![];
             update_data.write_u8(MoneyFunction::Unstake as u8)?;
             update.encode(&mut update_data)?;

+ 0 - 4
src/contract/money/src/state.rs

@@ -69,10 +69,6 @@ pub struct StakedOutput {
     pub coin_commit_hash: pallas::Base,
     /// coin pk hash
     pub coin_pk_hash: pallas::Base,
-    /// The encrypted note ciphertext
-    //pub ciphertext: Vec<u8>,
-    /// The ephemeral public key
-    //pub ephem_public: PublicKey,
 }
 
 /// Inputs and outputs for a payment