Ver Fonte

contract/consensus/proposal: validate input coin is not on unstake set

aggstam há 3 anos atrás
pai
commit
03a26f109c

+ 1 - 0
src/contract/consensus/src/client/proposal_v1.rs

@@ -166,6 +166,7 @@ impl ConsensusProposalCallBuilder {
 
         let input = ConsensusInput {
             epoch: self.coin.note.epoch,
+            coin: self.coin.coin,
             value_commit: public_inputs.value_commit,
             nullifier: public_inputs.nullifier,
             merkle_root: public_inputs.merkle_root,

+ 1 - 0
src/contract/consensus/src/client/stake_v1.rs

@@ -109,6 +109,7 @@ impl ConsensusStakeCallBuilder {
 
         let input = ConsensusInput {
             epoch: self.epoch,
+            coin: self.coin.coin,
             value_commit: public_inputs.value_commit,
             nullifier: self.nullifier,
             merkle_root: self.merkle_root,

+ 1 - 0
src/contract/consensus/src/client/unstake_request_v1.rs

@@ -90,6 +90,7 @@ impl ConsensusUnstakeRequestCallBuilder {
 
         let input = ConsensusInput {
             epoch: self.coin.note.epoch,
+            coin: self.coin.coin,
             value_commit: public_inputs.value_commit,
             nullifier: public_inputs.nullifier,
             merkle_root: public_inputs.merkle_root,

+ 2 - 1
src/contract/consensus/src/client/unstake_v1.rs

@@ -82,6 +82,7 @@ impl ConsensusUnstakeCallBuilder {
 
         let input = ConsensusInput {
             epoch: self.coin.note.epoch,
+            coin: self.coin.coin,
             value_commit: public_inputs.value_commit,
             nullifier: public_inputs.nullifier,
             merkle_root: public_inputs.merkle_root,
@@ -89,7 +90,7 @@ impl ConsensusUnstakeCallBuilder {
         };
 
         // We now fill this with necessary stuff
-        let params = ConsensusUnstakeParamsV1 { input, coin: self.coin.coin };
+        let params = ConsensusUnstakeParamsV1 { input };
         let proofs = vec![proof];
 
         // Now we should have all the params, zk proof, signature secret and token blind.

+ 6 - 0
src/contract/consensus/src/entrypoint/proposal_v1.rs

@@ -195,6 +195,12 @@ pub(crate) fn consensus_proposal_process_instruction_v1(
         return Err(MoneyError::DuplicateNullifier.into())
     }
 
+    // Check that the coin hasn't existed before in unstake set.
+    if db_contains_key(unstaked_coins_db, &serialize(&input.coin))? {
+        msg!("[ConsensusProposalV1] Error: Unstaked coin found in input");
+        return Err(MoneyError::DuplicateCoin.into())
+    }
+
     // Verify value commits match between burnt and mint inputs
     let mut valcom_total = pallas::Point::identity();
     valcom_total += input.value_commit;

+ 6 - 0
src/contract/consensus/src/entrypoint/unstake_request_v1.rs

@@ -137,6 +137,12 @@ pub(crate) fn consensus_unstake_request_process_instruction_v1(
         return Err(MoneyError::DuplicateNullifier.into())
     }
 
+    // Check that the coin hasn't existed before in unstake set.
+    if db_contains_key(unstaked_coins_db, &serialize(&input.coin))? {
+        msg!("[ConsensusUnstakeRequestV1] Error: Unstaked coin found in input");
+        return Err(MoneyError::DuplicateCoin.into())
+    }
+
     msg!("[ConsensusUnstakeRequestV1] Validating anonymous output");
 
     // Verify value commits match

+ 1 - 1
src/contract/consensus/src/entrypoint/unstake_v1.rs

@@ -109,7 +109,7 @@ pub(crate) fn consensus_unstake_process_instruction_v1(
     }
 
     // Check that the coin exists in unstake set.
-    if !db_contains_key(unstaked_coins_db, &serialize(&params.coin))? {
+    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())
     }

+ 1 - 0
src/contract/money/src/client/unstake_v1.rs

@@ -147,6 +147,7 @@ impl MoneyUnstakeCallBuilder {
 
         let input = ConsensusInput {
             epoch: self.coin.note.epoch,
+            coin: self.coin.coin,
             value_commit: public_inputs.value_commit,
             nullifier: self.nullifier,
             merkle_root: self.merkle_root,

+ 2 - 2
src/contract/money/src/model.rs

@@ -101,6 +101,8 @@ pub struct Input {
 pub struct ConsensusInput {
     /// Epoch the coin was minted
     pub epoch: u64,
+    /// The coin
+    pub coin: Coin,
     /// Pedersen commitment for the staked coin's value
     pub value_commit: pallas::Point,
     /// Revealed nullifier
@@ -256,8 +258,6 @@ pub struct ConsensusStakeUpdateV1 {
 pub struct ConsensusUnstakeParamsV1 {
     /// Anonymous input
     pub input: ConsensusInput,
-    /// The unstaked coin
-    pub coin: Coin,
 }
 
 /// State update for `Consensus::Unstake`