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

contract/consensus: Clean up and reorder UnstakeV1 state transition

parazyd пре 3 година
родитељ
комит
cbbbd18ff6
1 измењених фајлова са 28 додато и 42 уклоњено
  1. 28 42
      src/contract/consensus/src/entrypoint/unstake_v1.rs

+ 28 - 42
src/contract/consensus/src/entrypoint/unstake_v1.rs

@@ -19,8 +19,8 @@
 use darkfi_money_contract::{
     error::MoneyError,
     model::{ConsensusUnstakeParamsV1, ConsensusUnstakeUpdateV1, MoneyUnstakeParamsV1},
-    CONSENSUS_CONTRACT_NULLIFIERS_TREE, CONSENSUS_CONTRACT_UNSTAKED_COINS_TREE,
-    CONSENSUS_CONTRACT_UNSTAKED_COIN_ROOTS_TREE, CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1,
+    MoneyFunction, CONSENSUS_CONTRACT_NULLIFIERS_TREE, CONSENSUS_CONTRACT_UNSTAKED_COIN_ROOTS_TREE,
+    CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1,
 };
 use darkfi_sdk::{
     crypto::{pasta_prelude::*, ContractId, MONEY_CONTRACT_ID},
@@ -33,7 +33,7 @@ use darkfi_sdk::{
 };
 use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
 
-use crate::{error::ConsensusError, model::calculate_grace_period, ConsensusFunction};
+use crate::{error::ConsensusError, model::GRACE_PERIOD, ConsensusFunction};
 
 /// `get_metadata` function for `Consensus::UnstakeV1`
 pub(crate) fn consensus_unstake_get_metadata_v1(
@@ -50,11 +50,10 @@ pub(crate) fn consensus_unstake_get_metadata_v1(
     // Public keys for the transaction signatures we have to verify
     let signature_pubkeys = vec![input.signature_public];
 
-    // Grab the pedersen commitments and signature pubkeys from the
+    // Grab the pedersen commitment and signature pubkey coordinates from the
     // anonymous input
     let value_coords = input.value_commit.to_affine().coordinates().unwrap();
     let (sig_x, sig_y) = input.signature_public.xy();
-    let epoch_palas = pallas::Base::from(input.epoch);
 
     // It is very important that these are in the same order as the
     // `constrain_instance` calls in the zkas code.
@@ -63,7 +62,7 @@ pub(crate) fn consensus_unstake_get_metadata_v1(
         CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1.to_string(),
         vec![
             input.nullifier.inner(),
-            epoch_palas,
+            pallas::Base::from(input.epoch),
             sig_x,
             sig_y,
             input.merkle_root.inner(),
@@ -76,7 +75,6 @@ pub(crate) fn consensus_unstake_get_metadata_v1(
     let mut metadata = vec![];
     zk_public_inputs.encode(&mut metadata)?;
     signature_pubkeys.encode(&mut metadata)?;
-
     Ok(metadata)
 }
 
@@ -93,42 +91,12 @@ pub(crate) fn consensus_unstake_process_instruction_v1(
     // Access the necessary databases where there is information to
     // validate this state transition.
     let nullifiers_db = db_lookup(cid, CONSENSUS_CONTRACT_NULLIFIERS_TREE)?;
-    let unstaked_coins_db = db_lookup(cid, CONSENSUS_CONTRACT_UNSTAKED_COINS_TREE)?;
     let unstaked_coin_roots_db = db_lookup(cid, CONSENSUS_CONTRACT_UNSTAKED_COIN_ROOTS_TREE)?;
 
     // ===================================
     // Perform the actual state transition
     // ===================================
 
-    msg!("[ConsensusUnstakeV1] Validating anonymous input");
-
-    // The coin has passed through the grace period and is allowed to get unstaked.
-    if get_verifying_slot_epoch() - input.epoch <= calculate_grace_period() {
-        msg!("[ConsensusUnstakeV1] Error: Coin is not allowed to get unstaked yet");
-        return Err(ConsensusError::CoinStillInGracePeriod.into())
-    }
-
-    /*
-    // Check that the coin exists in unstake set.
-    if !db_contains_key(unstaked_coins_db, &serialize(&input.coin))? {
-        msg!("[GenesisStakeV1] Error: Unstaked coin is not in unstake set");
-        return Err(ConsensusError::CoinNotInUnstakeSet.into())
-    }
-    */
-
-    // The Merkle root is used to know whether this is an unstaked coin that
-    // existed in a previous state.
-    if !db_contains_key(unstaked_coin_roots_db, &serialize(&input.merkle_root))? {
-        msg!("[ConsensusUnstakeV1] Error: Merkle root not found in previous state");
-        return Err(MoneyError::TransferMerkleRootNotFound.into())
-    }
-
-    // The nullifiers should not already exist. It is the double-spend protection.
-    if db_contains_key(nullifiers_db, &serialize(&input.nullifier))? {
-        msg!("[ConsensusUnstakeV1] Error: Duplicate nullifier found");
-        return Err(MoneyError::DuplicateNullifier.into())
-    }
-
     // Check next call is money contract
     let next_call_idx = call_idx + 1;
     if next_call_idx >= calls.len() as u32 {
@@ -142,26 +110,44 @@ pub(crate) fn consensus_unstake_process_instruction_v1(
         return Err(MoneyError::UnstakeNextCallNotMoneyContract.into())
     }
 
-    // Verify next call corresponds to Money::UnstakeV1 (0x07)
-    if next.data[0] != 0x07 {
+    // Verify next call corresponds to Money::UnstakeV1
+    if next.data[0] != MoneyFunction::UnstakeV1 as u8 {
         msg!("[ConsensusUnstakeV1] Error: Next call function mismatch");
         return Err(MoneyError::NextCallFunctionMismatch.into())
     }
 
-    // Verify next call StakeInput is the same as this calls input
+    // Verify next call input is the same as this calls input
     let next_params: MoneyUnstakeParamsV1 = deserialize(&next.data[1..])?;
     if input != &next_params.input {
         msg!("[ConsensusUnstakeV1] Error: Next call input mismatch");
         return Err(MoneyError::NextCallInputMismatch.into())
     }
 
+    msg!("[ConsensusUnstakeV1] Validating anonymous input");
+    // The coin has passed through the grace period and is allowed to get unstaked.
+    if get_verifying_slot_epoch() - input.epoch <= GRACE_PERIOD {
+        msg!("[ConsensusUnstakeV1] Error: Coin is not allowed to get unstaked yet");
+        return Err(ConsensusError::CoinStillInGracePeriod.into())
+    }
+
+    // The Merkle root is used to know whether this is an unstaked coin that
+    // existed in a previous state.
+    if !db_contains_key(unstaked_coin_roots_db, &serialize(&input.merkle_root))? {
+        msg!("[ConsensusUnstakeV1] Error: Merkle root not found in previous state");
+        return Err(MoneyError::TransferMerkleRootNotFound.into())
+    }
+
+    // The nullifiers should not already exist. It is the double-spend protection.
+    if db_contains_key(nullifiers_db, &serialize(&input.nullifier))? {
+        msg!("[ConsensusUnstakeV1] Error: Duplicate nullifier found");
+        return Err(MoneyError::DuplicateNullifier.into())
+    }
+
     // At this point the state transition has passed, so we create a state update
     let update = ConsensusUnstakeUpdateV1 { nullifier: input.nullifier };
     let mut update_data = vec![];
     update_data.write_u8(ConsensusFunction::UnstakeV1 as u8)?;
     update.encode(&mut update_data)?;
-
-    // and return it
     Ok(update_data)
 }