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

contract/consensus: use constants for pallas::Base

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

+ 22 - 6
script/research/pallas_constants/src/main.rs

@@ -26,7 +26,7 @@ use anyhow::Result;
 use darkfi::consensus::lead_coin::LeadCoin;
 use darkfi_sdk::{crypto::pasta_prelude::PrimeField, pasta::pallas};
 
-/// Generate a string represenation of a pallas::Base constant
+/// Generate a string represenation of a `pallas::Base` constant
 fn to_constant(name: &str, x: pallas::Base, public: bool) -> String {
     let repr = x.to_repr();
     let mut res = [0_u64; 4];
@@ -41,10 +41,14 @@ fn to_constant(name: &str, x: pallas::Base, public: bool) -> String {
     format!("{p} const {name}: pallas::Base = pallas::Base::from_raw({res:?});\n")
 }
 
-/// Generate constants for corresponding pallas::Base.
+/// Generate constants for corresponding `pallas::Base`
 fn main() -> Result<()> {
     let mut source = String::new();
-    source.push_str(&to_constant("HEADSTART", LeadCoin::headstart(), false));
+    source.push_str(&to_constant("REWARD_PALLAS", pallas::Base::one(), true));
+    source.push_str(&to_constant("SEED_PREFIX", pallas::Base::from(3), true));
+    source.push_str(&to_constant("MU_Y_PREFIX", pallas::Base::from(22), true));
+    source.push_str(&to_constant("MU_RHO_PREFIX", pallas::Base::from(5), true));
+    source.push_str(&to_constant("HEADSTART", LeadCoin::headstart(), true));
 
     let mut cmd = Command::new("rustfmt");
     cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
@@ -79,15 +83,27 @@ mod tests {
         let zero = pallas::Base::zero();
         let zero_arr = [0, 0, 0, 0];
 
-        let one = pallas::Base::one();
-        let one_arr = [1, 0, 0, 0];
+        let reward = pallas::Base::one();
+        let reward_arr = [1, 0, 0, 0];
+
+        let seed_prefix = pallas::Base::from(3);
+        let seed_prefix_arr = [3, 0, 0, 0];
+
+        let mu_y_prefix = pallas::Base::from(22);
+        let mu_y_prefix_arr = [22, 0, 0, 0];
+
+        let mu_rho_prefix = pallas::Base::from(5);
+        let mu_rho_prefix_arr = [5, 0, 0, 0];
 
         let headstart = LeadCoin::headstart();
         let headstart_arr =
             [11731824086999220879, 11830614503713258191, 737869762948382064, 46116860184273879];
 
         assert_eq!(zero, pallas::Base::from_raw(zero_arr));
-        assert_eq!(one, pallas::Base::from_raw(one_arr));
+        assert_eq!(reward, pallas::Base::from_raw(reward_arr));
+        assert_eq!(seed_prefix, pallas::Base::from_raw(seed_prefix_arr));
+        assert_eq!(mu_y_prefix, pallas::Base::from_raw(mu_y_prefix_arr));
+        assert_eq!(mu_rho_prefix, pallas::Base::from_raw(mu_rho_prefix_arr));
         assert_eq!(headstart, pallas::Base::from_raw(headstart_arr));
     }
 }

+ 9 - 9
src/contract/consensus/src/client/proposal_v1.rs

@@ -44,7 +44,10 @@ use crate::{
         stake_v1::{create_stake_mint_proof, TransactionBuilderOutputInfo as StakeTBOI},
         unstake_v1::{create_unstake_burn_proof, TransactionBuilderInputInfo as UnstakeTBII},
     },
-    model::{ConsensusRewardParamsV1, REWARD},
+    model::{
+        ConsensusRewardParamsV1, HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD, REWARD_PALLAS,
+        SEED_PREFIX, ZERO,
+    },
 };
 
 pub struct ConsensusProposalCallDebris {
@@ -273,17 +276,14 @@ pub fn create_proposal_reward_proof(
     value_blind: pallas::Scalar,
 ) -> Result<(Proof, ConsensusProposalRewardRevealed)> {
     // Proof parameters
-    let zero = pallas::Base::from(0);
-    let seed_prefix = pallas::Base::from(3);
     let value_commit = pedersen_commitment_u64(value, value_blind);
     let new_value_commit = pedersen_commitment_u64(value + REWARD, value_blind);
     let slot_pallas = pallas::Base::from(slot_checkpoint.slot);
-    let mu_y = poseidon_hash([pallas::Base::from(22), slot_checkpoint.eta, slot_pallas]);
-    let seed = poseidon_hash([seed_prefix, coin, secret_key, zero]);
+    let seed = poseidon_hash([SEED_PREFIX, coin, secret_key, ZERO]);
+    let mu_y = poseidon_hash([MU_Y_PREFIX, slot_checkpoint.eta, slot_pallas]);
     let y = poseidon_hash([seed, mu_y]);
-    let mu_rho = poseidon_hash([pallas::Base::from(3), slot_checkpoint.eta, slot_pallas]);
+    let mu_rho = poseidon_hash([MU_RHO_PREFIX, slot_checkpoint.eta, slot_pallas]);
     let rho = poseidon_hash([seed, mu_rho]);
-    let headstart = darkfi::consensus::LeadCoin::headstart();
     let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2);
 
     // Generate public inputs, witnesses and proof
@@ -302,11 +302,11 @@ pub fn create_proposal_reward_proof(
         Witness::Base(Value::known(coin)),
         Witness::Base(Value::known(secret_key)),
         Witness::Base(Value::known(pallas::Base::from(value))),
-        Witness::Base(Value::known(pallas::Base::from(REWARD))),
+        Witness::Base(Value::known(REWARD_PALLAS)),
         Witness::Scalar(Value::known(value_blind)),
         Witness::Base(Value::known(mu_y)),
         Witness::Base(Value::known(mu_rho)),
-        Witness::Base(Value::known(headstart)),
+        Witness::Base(Value::known(HEADSTART)),
         Witness::Base(Value::known(sigma1)),
         Witness::Base(Value::known(sigma2)),
     ];

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

@@ -70,7 +70,6 @@ impl ConsensusUnstakeBurnRevealed {
             *tokcom_coords.x(),
             *tokcom_coords.y(),
             self.merkle_root.inner(),
-            // TODO: Why is spend hook in the struct but not here?
             self.user_data_enc,
             *sigpub_coords.x(),
             *sigpub_coords.y(),

+ 5 - 2
src/contract/consensus/src/entrypoint/proposal_burn_v1.rs

@@ -35,7 +35,10 @@ use darkfi_sdk::{
 };
 use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
 
-use crate::{model::ConsensusRewardParamsV1, ConsensusFunction};
+use crate::{
+    model::{ConsensusRewardParamsV1, ZERO},
+    ConsensusFunction,
+};
 
 /// `get_metadata` function for `Consensus::ProposalBurnV1`
 pub(crate) fn consensus_proposal_burn_get_metadata_v1(
@@ -140,7 +143,7 @@ pub(crate) fn consensus_proposal_burn_process_instruction_v1(
     }
 
     // Check if spend hook is set and its correctness
-    if input.spend_hook == pallas::Base::zero() {
+    if input.spend_hook == ZERO {
         msg!("[ConsensusProposalBurnV1] Error: Missing spend hook");
         return Err(MoneyError::StakeMissingSpendHook.into())
     }

+ 5 - 2
src/contract/consensus/src/entrypoint/proposal_mint_v1.rs

@@ -36,7 +36,10 @@ use darkfi_sdk::{
 };
 use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
 
-use crate::{model::ConsensusRewardParamsV1, ConsensusFunction};
+use crate::{
+    model::{ConsensusRewardParamsV1, ZERO},
+    ConsensusFunction,
+};
 
 /// `get_metadata` function for `Consensus::ProposalMintV1`
 pub(crate) fn consensus_proposal_mint_get_metadata_v1(
@@ -159,7 +162,7 @@ pub(crate) fn consensus_proposal_mint_process_instruction_v1(
 
     // If spend hook is set, check its correctness
     let previous_input = &previous_params.unstake_input;
-    if previous_input.spend_hook != pallas::Base::zero() &&
+    if previous_input.spend_hook != ZERO &&
         previous_input.spend_hook != CONSENSUS_CONTRACT_ID.inner()
     {
         msg!("[ConsensusProposalMintV1] Error: Invoking contract call does not match spend hook in input");

+ 7 - 4
src/contract/consensus/src/entrypoint/proposal_reward_v1.rs

@@ -36,7 +36,10 @@ use darkfi_serial::{deserialize, Encodable, WriteExt};
 
 use crate::{
     error::ConsensusError,
-    model::{ConsensusRewardParamsV1, ConsensusRewardUpdateV1, SlotCheckpoint, REWARD},
+    model::{
+        ConsensusRewardParamsV1, ConsensusRewardUpdateV1, SlotCheckpoint, MU_RHO_PREFIX,
+        MU_Y_PREFIX, REWARD, ZERO,
+    },
     ConsensusFunction,
 };
 
@@ -74,8 +77,8 @@ pub(crate) fn consensus_proposal_reward_get_metadata_v1(
 
     // Calculate election seeds
     let slot_pallas = pallas::Base::from(slot_checkpoint.slot);
-    let mu_y = poseidon_hash([pallas::Base::from(22), slot_checkpoint.eta, slot_pallas]);
-    let mu_rho = poseidon_hash([pallas::Base::from(3), slot_checkpoint.eta, slot_pallas]);
+    let mu_y = poseidon_hash([MU_Y_PREFIX, slot_checkpoint.eta, slot_pallas]);
+    let mu_rho = poseidon_hash([MU_RHO_PREFIX, slot_checkpoint.eta, slot_pallas]);
 
     // Grab sigmas from slot checkpoint
     let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2);
@@ -170,7 +173,7 @@ pub(crate) fn consensus_proposal_reward_process_instruction_v1(
     }
 
     // If spend hook is set, check its correctness
-    if previous_input.spend_hook != pallas::Base::zero() &&
+    if previous_input.spend_hook != ZERO &&
         previous_input.spend_hook != CONSENSUS_CONTRACT_ID.inner()
     {
         msg!("[ConsensusProposalRewardV1] Error: Invoking contract call does not match spend hook in input");

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

@@ -36,7 +36,7 @@ use darkfi_sdk::{
 };
 use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
 
-use crate::ConsensusFunction;
+use crate::{model::ZERO, ConsensusFunction};
 
 /// `get_metadata` function for `Consensus::StakeV1`
 pub(crate) fn consensus_stake_get_metadata_v1(
@@ -154,7 +154,7 @@ pub(crate) fn consensus_stake_process_instruction_v1(
     }
 
     // If spend hook is set, check its correctness
-    if previous_input.spend_hook != pallas::Base::zero() &&
+    if previous_input.spend_hook != ZERO &&
         previous_input.spend_hook != CONSENSUS_CONTRACT_ID.inner()
     {
         msg!("[ConsensusStakeV1] Error: Invoking contract call does not match spend hook in input");

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

@@ -35,7 +35,7 @@ use darkfi_sdk::{
 };
 use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
 
-use crate::ConsensusFunction;
+use crate::{model::ZERO, ConsensusFunction};
 
 /// `get_metadata` function for `Consensus::UnstakeV1`
 pub(crate) fn consensus_unstake_get_metadata_v1(
@@ -140,7 +140,7 @@ pub(crate) fn consensus_unstake_process_instruction_v1(
     }
 
     // Check if spend hook is set and its correctness
-    if input.spend_hook == pallas::Base::zero() {
+    if input.spend_hook == ZERO {
         msg!("[ConsensusUnstakeV1] Error: Missing spend hook");
         return Err(MoneyError::StakeMissingSpendHook.into())
     }

+ 21 - 1
src/contract/consensus/src/model.rs

@@ -41,8 +41,28 @@ pub struct ConsensusRewardParamsV1 {
 #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
 pub struct ConsensusRewardUpdateV1 {}
 
-// TODO: Don't set these here
+// Consensus parameters configuration.
+// Note: Always verify `pallas::Base` are correct, in case of changes,
+// using pallas_constants tool.
+// Configured reward
 pub const REWARD: u64 = 1;
+// Reward `pallas::Base`, calculated by: pallas::Base::from(REWARD)
+pub const REWARD_PALLAS: pallas::Base = pallas::Base::from_raw([1, 0, 0, 0]);
+// `pallas::Base` used as prefix/suffix in poseidon hash
+pub const ZERO: pallas::Base = pallas::Base::zero();
+// Seed prefix, calculated by: pallas::Base::from(3)
+pub const SEED_PREFIX: pallas::Base = pallas::Base::from_raw([3, 0, 0, 0]);
+// Election seed y prefix, calculated by: pallas::Base::from(22)
+pub const MU_Y_PREFIX: pallas::Base = pallas::Base::from_raw([22, 0, 0, 0]);
+// Election seed rho prefix, calculated by: pallas::Base::from(5)
+pub const MU_RHO_PREFIX: pallas::Base = pallas::Base::from_raw([5, 0, 0, 0]);
+// Lottery headstart, calculated by: darkfi::consensus::LeadCoin::headstart()
+pub const HEADSTART: pallas::Base = pallas::Base::from_raw([
+    11731824086999220879,
+    11830614503713258191,
+    737869762948382064,
+    46116860184273879,
+]);
 
 /// Auxiliary structure to decode `darkfi::consensus::state::SlotCheckpoint`
 /// to use in contract.