Просмотр исходного кода

contract/consensus: UstakeV1 fixed

aggstam 3 лет назад
Родитель
Сommit
3492666dfe

+ 2 - 2
src/contract/consensus/src/client/stake_v1.rs

@@ -31,7 +31,7 @@ use darkfi_sdk::{
     crypto::{
         note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base,
         pedersen_commitment_u64, poseidon_hash, Coin, MerkleNode, Nullifier, PublicKey, TokenId,
-        DARK_TOKEN_ID,
+        CONSENSUS_CONTRACT_ID, DARK_TOKEN_ID,
     },
     pasta::pallas,
 };
@@ -111,7 +111,7 @@ impl ConsensusStakeCallBuilder {
         debug!("Finished building output");
 
         let serial = pallas::Base::random(&mut OsRng);
-        let spend_hook = DARK_TOKEN_ID.inner();
+        let spend_hook = CONSENSUS_CONTRACT_ID.inner();
         let user_data = pallas::Base::random(&mut OsRng);
         let coin_blind = pallas::Base::random(&mut OsRng);
 

+ 4 - 7
src/contract/consensus/src/client/unstake_v1.rs

@@ -120,7 +120,6 @@ impl ConsensusUnstakeCallBuilder {
         let value_blind = pallas::Scalar::random(&mut OsRng);
         let token_blind = pallas::Scalar::random(&mut OsRng);
         let signature_secret = SecretKey::random(&mut OsRng);
-        let spend_hook = DARK_TOKEN_ID.inner();
         let user_data_blind = pallas::Base::random(&mut OsRng);
         info!("Creating unstake burn proof for input");
         let (proof, public_inputs) = create_unstake_burn_proof(
@@ -129,7 +128,6 @@ impl ConsensusUnstakeCallBuilder {
             &input,
             value_blind,
             token_blind,
-            spend_hook,
             user_data_blind,
             signature_secret,
         )?;
@@ -139,7 +137,7 @@ impl ConsensusUnstakeCallBuilder {
             token_commit: public_inputs.token_commit,
             nullifier: public_inputs.nullifier,
             merkle_root: public_inputs.merkle_root,
-            spend_hook,
+            spend_hook: public_inputs.spend_hook,
             user_data_enc: public_inputs.user_data_enc,
             signature_public: public_inputs.signature_public,
         };
@@ -161,7 +159,6 @@ pub fn create_unstake_burn_proof(
     input: &TransactionBuilderInputInfo,
     value_blind: pallas::Scalar,
     token_blind: pallas::Scalar,
-    spend_hook: pallas::Base,
     user_data_blind: pallas::Base,
     signature_secret: SecretKey,
 ) -> Result<(Proof, ConsensusUnstakeBurnRevealed)> {
@@ -177,7 +174,7 @@ pub fn create_unstake_burn_proof(
         pallas::Base::from(input.note.value),
         input.note.token_id.inner(),
         input.note.serial,
-        spend_hook,
+        input.note.spend_hook,
         input.note.user_data,
         input.note.coin_blind,
     ]);
@@ -205,7 +202,7 @@ pub fn create_unstake_burn_proof(
         token_commit,
         nullifier,
         merkle_root,
-        spend_hook,
+        spend_hook: input.note.spend_hook,
         user_data_enc,
         signature_public,
     };
@@ -216,7 +213,7 @@ pub fn create_unstake_burn_proof(
         Witness::Scalar(Value::known(value_blind)),
         Witness::Scalar(Value::known(token_blind)),
         Witness::Base(Value::known(input.note.serial)),
-        Witness::Base(Value::known(spend_hook)),
+        Witness::Base(Value::known(input.note.spend_hook)),
         Witness::Base(Value::known(input.note.user_data)),
         Witness::Base(Value::known(user_data_blind)),
         Witness::Base(Value::known(input.note.coin_blind)),

+ 29 - 15
src/contract/consensus/src/entrypoint/unstake_v1.rs

@@ -17,13 +17,13 @@
  */
 
 use darkfi_money_contract::{
-    error::MoneyError, CONSENSUS_CONTRACT_COIN_ROOTS_TREE, CONSENSUS_CONTRACT_NULLIFIERS_TREE,
-    CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1,
+    error::MoneyError, model::MoneyUnstakeParamsV1, CONSENSUS_CONTRACT_COIN_ROOTS_TREE,
+    CONSENSUS_CONTRACT_NULLIFIERS_TREE, CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1,
 };
 use darkfi_sdk::{
     crypto::{
-        pasta_prelude::*, pedersen_commitment_base, ContractId, PublicKey, DARK_TOKEN_ID,
-        MONEY_CONTRACT_ID,
+        pasta_prelude::*, pedersen_commitment_base, ContractId, PublicKey, CONSENSUS_CONTRACT_ID,
+        DARK_TOKEN_ID, MONEY_CONTRACT_ID,
     },
     db::{db_contains_key, db_lookup, db_set},
     error::{ContractError, ContractResult},
@@ -127,27 +127,41 @@ pub(crate) fn consensus_unstake_process_instruction_v1(
         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 {
+        msg!("[ConsensusUnstakeV1] Error: next_call_idx out of bounds");
+        return Err(MoneyError::SpendHookOutOfBounds.into())
+    }
+
+    let next = &calls[next_call_idx as usize];
+    if next.contract_id.inner() != MONEY_CONTRACT_ID.inner() {
+        msg!("[ConsensusUnstakeV1] Error: Next contract call is not money contract");
+        return Err(MoneyError::UnstakeNextCallNotMoneyContract.into())
+    }
+
     // Check if spend hook is set and its correctness
     if input.spend_hook == pallas::Base::zero() {
         msg!("[ConsensusUnstakeV1] Error: Missing spend hook");
         return Err(MoneyError::StakeMissingSpendHook.into())
     }
 
-    let next_call_idx = call_idx + 1;
-    if next_call_idx >= calls.len() as u32 {
-        msg!("[ConsensusUnstakeV1] Error: next_call_idx out of bounds");
-        return Err(MoneyError::SpendHookOutOfBounds.into())
+    if input.spend_hook != CONSENSUS_CONTRACT_ID.inner() {
+        msg!("[ConsensusUnstakeV1] Error: Spend hook is not consensus contract");
+        return Err(MoneyError::UnstakeSpendHookNotConsensusContract.into())
     }
 
-    let next = &calls[next_call_idx as usize];
-    if next.contract_id.inner() != input.spend_hook {
-        msg!("[ConsensusUnstakeV1] Error: Invoking contract call does not match spend hook");
-        return Err(MoneyError::SpendHookMismatch.into())
+    // Verify next call corresponds to Money::UnstakeV1 (0x06)
+    if next.data[0] != 0x06 {
+        msg!("[ConsensusUnstakeV1] Error: Next call function mismatch");
+        return Err(MoneyError::NextCallFunctionMissmatch.into())
     }
 
-    if input.spend_hook != MONEY_CONTRACT_ID.inner() {
-        msg!("[ConsensusUnstakeV1] Error: Spend hook is not money contract");
-        return Err(MoneyError::UnstakeSpendHookNotMoneyContract.into())
+    // Verify next call StakeInput 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::NextCallInputMissmatch.into())
     }
 
     // At this point the state transition has passed, so we create a state update

+ 11 - 7
src/contract/money/src/error.rs

@@ -89,8 +89,11 @@ pub enum MoneyError {
     #[error("Previous contract call is not money contract")]
     StakePreviousCallNotMoneyContract,
 
-    #[error("Spend hook is not money contract")]
-    UnstakeSpendHookNotMoneyContract,
+    #[error("Spend hook is not consensus contract")]
+    UnstakeSpendHookNotConsensusContract,
+
+    #[error("Next contract call is not money contract")]
+    UnstakeNextCallNotMoneyContract,
 
     #[error("Next call function mismatch")]
     NextCallFunctionMissmatch,
@@ -131,11 +134,12 @@ impl From<MoneyError> for ContractError {
             MoneyError::StakeMissingNullifier => Self::Custom(21),
             MoneyError::StakeNextCallNotConsensusContract => Self::Custom(22),
             MoneyError::StakePreviousCallNotMoneyContract => Self::Custom(23),
-            MoneyError::UnstakeSpendHookNotMoneyContract => Self::Custom(24),
-            MoneyError::NextCallFunctionMissmatch => Self::Custom(25),
-            MoneyError::NextCallInputMissmatch => Self::Custom(26),
-            MoneyError::PreviousCallFunctionMissmatch => Self::Custom(27),
-            MoneyError::PreviousCallInputMissmatch => Self::Custom(28),
+            MoneyError::UnstakeSpendHookNotConsensusContract => Self::Custom(24),
+            MoneyError::UnstakeNextCallNotMoneyContract => Self::Custom(25),
+            MoneyError::NextCallFunctionMissmatch => Self::Custom(26),
+            MoneyError::NextCallInputMissmatch => Self::Custom(27),
+            MoneyError::PreviousCallFunctionMissmatch => Self::Custom(28),
+            MoneyError::PreviousCallInputMissmatch => Self::Custom(29),
         }
     }
 }