diff --git a/src/contract/consensus/src/client/common.rs b/src/contract/consensus/src/client/common.rs index 91a63ff96..0ed8262f0 100644 --- a/src/contract/consensus/src/client/common.rs +++ b/src/contract/consensus/src/client/common.rs @@ -23,24 +23,17 @@ use darkfi::{ zkas::ZkBinary, Result, }; -use darkfi_money_contract::client::{ConsensusNote, MoneyNote}; +use darkfi_money_contract::client::ConsensusNote; use darkfi_sdk::{ crypto::{ - pasta_prelude::*, pedersen_commitment_base, pedersen_commitment_u64, poseidon_hash, Coin, - MerkleNode, MerklePosition, Nullifier, PublicKey, SecretKey, + pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, Coin, MerkleNode, MerklePosition, + Nullifier, PublicKey, SecretKey, }, incrementalmerkletree::Hashable, pasta::pallas, }; use rand::rngs::OsRng; -pub struct TransactionBuilderInputInfo { - pub leaf_position: MerklePosition, - pub merkle_path: Vec, - pub secret: SecretKey, - pub note: MoneyNote, -} - pub struct ConsensusMintOutputInfo { pub value: u64, pub epoch: u64, @@ -200,112 +193,3 @@ pub fn create_consensus_burn_proof( Ok((proof, public_inputs, input.secret)) } - -// TODO: Remove everything following -pub struct ConsensusUnstakeBurnRevealed { - pub value_commit: pallas::Point, - pub token_commit: pallas::Point, - pub nullifier: Nullifier, - pub merkle_root: MerkleNode, - pub spend_hook: pallas::Base, - pub user_data_enc: pallas::Base, - pub signature_public: PublicKey, -} - -impl ConsensusUnstakeBurnRevealed { - pub fn to_vec(&self) -> Vec { - let valcom_coords = self.value_commit.to_affine().coordinates().unwrap(); - let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap(); - let sigpub_coords = self.signature_public.inner().to_affine().coordinates().unwrap(); - - // NOTE: It's important to keep these in the same order - // as the `constrain_instance` calls in the zkas code. - vec![ - self.nullifier.inner(), - *valcom_coords.x(), - *valcom_coords.y(), - *tokcom_coords.x(), - *tokcom_coords.y(), - self.merkle_root.inner(), - self.user_data_enc, - *sigpub_coords.x(), - *sigpub_coords.y(), - ] - } -} - -pub fn create_unstake_burn_proof( - zkbin: &ZkBinary, - pk: &ProvingKey, - input: &TransactionBuilderInputInfo, - value_blind: pallas::Scalar, - token_blind: pallas::Scalar, - user_data_blind: pallas::Base, - signature_secret: SecretKey, -) -> Result<(Proof, ConsensusUnstakeBurnRevealed)> { - let nullifier = Nullifier::from(poseidon_hash([input.secret.inner(), input.note.serial])); - let public_key = PublicKey::from_secret(input.secret); - let (pub_x, pub_y) = public_key.xy(); - - let signature_public = PublicKey::from_secret(signature_secret); - - let coin = poseidon_hash([ - pub_x, - pub_y, - pallas::Base::from(input.note.value), - input.note.token_id.inner(), - input.note.serial, - input.note.spend_hook, - input.note.user_data, - input.note.coin_blind, - ]); - - let merkle_root = { - let position: u64 = input.leaf_position.into(); - let mut current = MerkleNode::from(coin); - for (level, sibling) in input.merkle_path.iter().enumerate() { - let level = level as u8; - current = if position & (1 << level) == 0 { - MerkleNode::combine(level.into(), ¤t, sibling) - } else { - MerkleNode::combine(level.into(), sibling, ¤t) - }; - } - current - }; - - let user_data_enc = poseidon_hash([input.note.user_data, user_data_blind]); - let value_commit = pedersen_commitment_u64(input.note.value, value_blind); - let token_commit = pedersen_commitment_base(input.note.token_id.inner(), token_blind); - - let public_inputs = ConsensusUnstakeBurnRevealed { - value_commit, - token_commit, - nullifier, - merkle_root, - spend_hook: input.note.spend_hook, - user_data_enc, - signature_public, - }; - - let prover_witnesses = vec![ - Witness::Base(Value::known(pallas::Base::from(input.note.value))), - Witness::Base(Value::known(input.note.token_id.inner())), - Witness::Scalar(Value::known(value_blind)), - Witness::Scalar(Value::known(token_blind)), - Witness::Base(Value::known(input.note.serial)), - 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)), - Witness::Base(Value::known(input.secret.inner())), - Witness::Uint32(Value::known(u64::from(input.leaf_position).try_into().unwrap())), - Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())), - Witness::Base(Value::known(signature_secret.inner())), - ]; - - let circuit = ZkCircuit::new(prover_witnesses, zkbin.clone()); - let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?; - - Ok((proof, public_inputs)) -} diff --git a/src/contract/consensus/src/client/mod.rs b/src/contract/consensus/src/client/mod.rs index 342c864fb..519d3819e 100644 --- a/src/contract/consensus/src/client/mod.rs +++ b/src/contract/consensus/src/client/mod.rs @@ -35,12 +35,7 @@ pub mod genesis_stake_v1; pub mod stake_v1; /// Proposal transaction building API. -/// This transaction is a chain of `Consensus::ProposalBurnV1`, `Consensus::ProposalRewardV1` -/// and `Consensus::ProposalMintV1` contract calls. pub mod proposal_v1; -/// Proposal transaction building API. -pub mod proposal_v1_2; - /// `Consensus::UnstakeV1` API pub mod unstake_v1; diff --git a/src/contract/consensus/src/client/proposal_v1.rs b/src/contract/consensus/src/client/proposal_v1.rs index 181ef624e..b320dba29 100644 --- a/src/contract/consensus/src/client/proposal_v1.rs +++ b/src/contract/consensus/src/client/proposal_v1.rs @@ -25,53 +25,45 @@ use darkfi::{ Result, }; use darkfi_money_contract::{ - client::{MoneyNote, OwnCoin}, - model::{ConsensusInput, Input, Output, PALLAS_ZERO}, + client::{ConsensusNote, ConsensusOwnCoin}, + model::{ConsensusInput, ConsensusOutput, PALLAS_ZERO}, }; use darkfi_sdk::{ crypto::{ ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base, - pedersen_commitment_u64, poseidon_hash, Coin, MerkleTree, Nullifier, PublicKey, SecretKey, - TokenId, CONSENSUS_CONTRACT_ID, DARK_TOKEN_ID, + pedersen_commitment_u64, poseidon_hash, Coin, MerkleNode, MerkleTree, Nullifier, PublicKey, + SecretKey, }, - incrementalmerkletree::Tree, + incrementalmerkletree::{Hashable, Tree}, pasta::{group::ff::FromUniformBytes, pallas}, }; -use log::{debug, info}; +use log::debug; use rand::rngs::OsRng; use crate::{ - client::common::{create_unstake_burn_proof, TransactionBuilderInputInfo as UnstakeTBII}, + client::common::{ConsensusBurnInputInfo, ConsensusMintOutputInfo}, model::{ - ConsensusProposalBurnParamsV1, ConsensusProposalMintParamsV1, - ConsensusProposalRewardParamsV1, HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD, - REWARD_PALLAS, SEED_PREFIX, SERIAL_PREFIX, + ConsensusProposalParamsV1, HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD, REWARD_PALLAS, + SEED_PREFIX, SERIAL_PREFIX, }, }; -// TODO: Remove TransactionBuilderOutputInfo -pub struct TransactionBuilderOutputInfo { - pub value: u64, - pub token_id: TokenId, - pub public_key: PublicKey, -} - pub struct ConsensusProposalCallDebris { - pub burn_params: ConsensusProposalBurnParamsV1, - pub burn_proofs: Vec, - pub reward_params: ConsensusProposalRewardParamsV1, - pub reward_proofs: Vec, - pub mint_params: ConsensusProposalMintParamsV1, - pub mint_proofs: Vec, + pub params: ConsensusProposalParamsV1, + pub proofs: Vec, pub signature_secret: SecretKey, } -pub struct ConsensusProposalRewardRevealed { +pub struct ConsensusProposalRevealed { pub nullifier: Nullifier, + pub epoch: u64, pub public_key: PublicKey, + pub merkle_root: MerkleNode, pub value_commit: pallas::Point, + pub new_serial: pallas::Base, pub new_serial_commit: pallas::Point, pub new_value_commit: pallas::Point, + pub new_coin: Coin, pub vrf_proof: VrfProof, pub mu_y: pallas::Base, pub y: pallas::Base, @@ -81,25 +73,31 @@ pub struct ConsensusProposalRewardRevealed { pub sigma2: pallas::Base, } -impl ConsensusProposalRewardRevealed { +impl ConsensusProposalRevealed { pub fn to_vec(&self) -> Vec { + let epoch_palas = pallas::Base::from(self.epoch); let (pub_x, pub_y) = self.public_key.xy(); let value_coords = self.value_commit.to_affine().coordinates().unwrap(); let new_serial_coords = self.new_serial_commit.to_affine().coordinates().unwrap(); + let reward_pallas = pallas::Base::from(REWARD); let new_value_coords = self.new_value_commit.to_affine().coordinates().unwrap(); // NOTE: It's important to keep these in the same order // as the `constrain_instance` calls in the zkas code. vec![ self.nullifier.inner(), + epoch_palas, pub_x, pub_y, + self.merkle_root.inner(), *value_coords.x(), *value_coords.y(), *new_serial_coords.x(), *new_serial_coords.y(), + reward_pallas, *new_value_coords.x(), *new_value_coords.y(), + self.new_coin.inner(), self.mu_y, self.y, self.mu_rho, @@ -111,258 +109,180 @@ impl ConsensusProposalRewardRevealed { } } -pub struct ConsensusProposalMintRevealed { - pub coin: Coin, - pub value_commit: pallas::Point, - pub token_commit: pallas::Point, - pub serial_commit: pallas::Point, -} - -impl ConsensusProposalMintRevealed { - pub fn to_vec(&self) -> Vec { - let valcom_coords = self.value_commit.to_affine().coordinates().unwrap(); - let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap(); - let sercom_coords = self.serial_commit.to_affine().coordinates().unwrap(); - - // NOTE: It's important to keep these in the same order - // as the `constrain_instance` calls in the zkas code. - vec![ - self.coin.inner(), - *valcom_coords.x(), - *valcom_coords.y(), - *tokcom_coords.x(), - *tokcom_coords.y(), - *sercom_coords.x(), - *sercom_coords.y(), - ] - } -} - /// Struct holding necessary information to build a proposal transaction. pub struct ConsensusProposalCallBuilder { - /// `OwnCoin` we're given to use in this builder - pub coin: OwnCoin, - /// Recipient's public key - pub recipient: PublicKey, + /// `ConsensusOwnCoin` we're given to use in this builder + pub coin: ConsensusOwnCoin, /// Rewarded slot checkpoint pub slot_checkpoint: SlotCheckpoint, /// Merkle tree of coins used to create inclusion proofs pub tree: MerkleTree, - /// `Burn_V1` zkas circuit ZkBinary - pub burn_zkbin: ZkBinary, - /// Proving key for the `Burn_V1` zk circuit - pub burn_pk: ProvingKey, - /// `ProposalReward_V1` zkas circuit ZkBinary - pub reward_zkbin: ZkBinary, - /// Proving key for the `Reward_V1` zk circuit - pub reward_pk: ProvingKey, - /// `ProposalMint_V1` zkas circuit ZkBinary - pub mint_zkbin: ZkBinary, - /// Proving key for the `Mint_V1` zk circuit - pub mint_pk: ProvingKey, + /// `Proposal_V1` zkas circuit ZkBinary + pub proposal_zkbin: ZkBinary, + /// Proving key for the `Proposal_V1` zk circuit + pub proposal_pk: ProvingKey, } impl ConsensusProposalCallBuilder { pub fn build(&self) -> Result { debug!("Building Consensus::ProposalBurnV1 contract call for proposal"); let value = self.coin.note.value; - let token_id = self.coin.note.token_id; assert!(value != 0); - assert!(token_id == *DARK_TOKEN_ID); - debug!("Building anonymous input for proposal"); + debug!("Building Consensus::ProposalV1 anonymous input"); let leaf_position = self.coin.leaf_position; let root = self.tree.root(0).unwrap(); let merkle_path = self.tree.authentication_path(leaf_position, &root).unwrap(); - let input = UnstakeTBII { + let input = ConsensusBurnInputInfo { leaf_position, merkle_path, secret: self.coin.secret, note: self.coin.note.clone(), + value_blind: pallas::Scalar::random(&mut OsRng), }; - debug!("Finished building input for proposal"); - let value_blind = pallas::Scalar::random(&mut OsRng); - let token_blind = pallas::Scalar::random(&mut OsRng); - let signature_secret = SecretKey::random(&mut OsRng); - let user_data_blind = pallas::Base::random(&mut OsRng); - info!("Creating unstake burn proof for input for proposal"); - let (proof, public_inputs) = create_unstake_burn_proof( - &self.burn_zkbin, - &self.burn_pk, + debug!("Building anonymous output"); + let reward_blind = pallas::Scalar::random(&mut OsRng); + let new_value_blind = input.value_blind + reward_blind; + let new_coin_blind = pallas::Base::random(&mut OsRng); + let output = ConsensusMintOutputInfo { + value: self.coin.note.value + REWARD, + epoch: 0, + public_key: PublicKey::from_secret(self.coin.secret), + value_blind: new_value_blind, + serial: self.coin.note.serial, + coin_blind: new_coin_blind, + }; + debug!("Finished building output"); + + debug!("Building Consensus::ProposalV1 contract call for proposal"); + let (proof, public_inputs) = create_proposal_proof( + &self.proposal_zkbin, + &self.proposal_pk, &input, - value_blind, - token_blind, - user_data_blind, - signature_secret, + &output, + &self.slot_checkpoint, )?; - let input = Input { + let input = ConsensusInput { + epoch: self.coin.note.epoch, value_commit: public_inputs.value_commit, - token_commit: public_inputs.token_commit, nullifier: public_inputs.nullifier, merkle_root: public_inputs.merkle_root, - spend_hook: public_inputs.spend_hook, - user_data_enc: public_inputs.user_data_enc, - signature_public: public_inputs.signature_public, + signature_public: public_inputs.public_key, }; - // We now fill this with necessary stuff - let burnt_secret_key = self.coin.secret.inner(); - let public_key = PublicKey::from_secret(burnt_secret_key.into()); - let burn_params = - ConsensusProposalBurnParamsV1 { token_blind, input: input.clone(), public_key }; - let burn_proofs = vec![proof]; - let burnt_input = input; - - debug!("Building Consensus::ProposalMintV1 contract call for proposal"); - let new_value = value + REWARD; - let nullifier = public_inputs.nullifier; - let merkle_root = public_inputs.merkle_root; - let signature_public = public_inputs.signature_public; - - debug!("Building anonymous output for proposal"); - let output = - TransactionBuilderOutputInfo { value: new_value, token_id, public_key: self.recipient }; - debug!("Finished building output for proposal"); - - let burnt_serial = self.coin.note.serial; - let spend_hook = CONSENSUS_CONTRACT_ID.inner(); - let user_data = pallas::Base::random(&mut OsRng); - let coin_blind = pallas::Base::random(&mut OsRng); - let serial_blind = pallas::Scalar::random(&mut OsRng); - - info!("Creating stake mint proof for output for proposal"); - let (proof, public_inputs, serial) = create_proposal_mint_proof( - &self.mint_zkbin, - &self.mint_pk, - &output, - value_blind, - token_blind, - serial_blind, - burnt_secret_key, - burnt_serial, - spend_hook, - user_data, - coin_blind, - )?; - // Encrypted note - let note = MoneyNote { - serial, + let note = ConsensusNote { + serial: public_inputs.new_serial, value: output.value, - token_id: output.token_id, - spend_hook, - user_data, - coin_blind, - value_blind, - token_blind, - memo: vec![], + epoch: 0, + coin_blind: new_coin_blind, + value_blind: new_value_blind, + reward: REWARD, + reward_blind, }; let encrypted_note = AeadEncryptedNote::encrypt(¬e, &output.public_key, &mut OsRng)?; - let output = Output { - value_commit: public_inputs.value_commit, - token_commit: public_inputs.token_commit, - coin: public_inputs.coin, + let output = ConsensusOutput { + value_commit: public_inputs.new_value_commit, + coin: public_inputs.new_coin, note: encrypted_note, }; - // TODO: epoch = current - let input = ConsensusInput { - epoch: 0, - value_commit: public_inputs.value_commit, - nullifier, - merkle_root, - signature_public, - }; - // We now fill this with necessary stuff - let serial_commit = public_inputs.serial_commit; - let mint_params = ConsensusProposalMintParamsV1 { - input: input.clone(), - output: output.clone(), - serial_commit, - }; - let mint_proofs = vec![proof]; - let mint_input = input; - - debug!("Building Consensus::ProposalRewardV1 contract call for proposal"); - let secret_key = self.coin.secret.inner(); - let serial = self.coin.note.serial; - let (proof, public_inputs) = create_proposal_reward_proof( - &self.reward_zkbin, - &self.reward_pk, - &self.slot_checkpoint, - secret_key, - serial, - value, - value_blind, - serial_blind, - )?; - - // We now fill this with necessary stuff - let burnt_public_key = public_inputs.public_key; - let new_serial_commit = serial_commit; + let new_serial_commit = public_inputs.new_serial_commit; let slot = self.slot_checkpoint.slot; let vrf_proof = public_inputs.vrf_proof; let y = public_inputs.y; let rho = public_inputs.rho; - let reward_params = ConsensusProposalRewardParamsV1 { - burnt_input, - burnt_public_key, - mint_input, + let params = ConsensusProposalParamsV1 { + input, output, + reward: REWARD, + reward_blind, new_serial_commit, slot, vrf_proof, y, rho, }; - let reward_proofs = vec![proof]; + let proofs = vec![proof]; // Now we should have all the params, zk proofs and signature secret. // We return it all and let the caller deal with it. - let debris = ConsensusProposalCallDebris { - burn_params, - burn_proofs, - reward_params, - reward_proofs, - mint_params, - mint_proofs, - signature_secret, - }; + let debris = + ConsensusProposalCallDebris { params, proofs, signature_secret: self.coin.secret }; Ok(debris) } } -#[allow(clippy::too_many_arguments)] -pub fn create_proposal_reward_proof( +pub fn create_proposal_proof( zkbin: &ZkBinary, pk: &ProvingKey, + input: &ConsensusBurnInputInfo, + output: &ConsensusMintOutputInfo, slot_checkpoint: &SlotCheckpoint, - secret_key: pallas::Base, - serial: pallas::Base, - value: u64, - value_blind: pallas::Scalar, - new_serial_blind: pallas::Scalar, -) -> Result<(Proof, ConsensusProposalRewardRevealed)> { +) -> Result<(Proof, ConsensusProposalRevealed)> { // Proof parameters - let nullifier = Nullifier::from(poseidon_hash([secret_key, serial])); - let public_key = PublicKey::from_secret(secret_key.into()); - let value_commit = pedersen_commitment_u64(value, value_blind); - let new_serial = poseidon_hash([SERIAL_PREFIX, secret_key, serial, PALLAS_ZERO]); + let nullifier = Nullifier::from(poseidon_hash([input.secret.inner(), input.note.serial])); + let epoch = input.note.epoch; + let epoch_pallas = pallas::Base::from(epoch); + let value_pallas = pallas::Base::from(input.note.value); + let value_commit = pedersen_commitment_u64(input.note.value, input.value_blind); + let public_key = PublicKey::from_secret(input.secret); + let (pub_x, pub_y) = public_key.xy(); + + // Burnt coin and its merkle_root + let coin = poseidon_hash([ + pub_x, + pub_y, + value_pallas, + epoch_pallas, + input.note.serial, + input.note.coin_blind, + ]); + + let merkle_root = { + let position: u64 = input.leaf_position.into(); + let mut current = MerkleNode::from(coin); + for (level, sibling) in input.merkle_path.iter().enumerate() { + let level = level as u8; + current = if position & (1 << level) == 0 { + MerkleNode::combine(level.into(), ¤t, sibling) + } else { + MerkleNode::combine(level.into(), sibling, ¤t) + }; + } + current + }; + + // New coin + let new_serial = poseidon_hash([SERIAL_PREFIX, input.secret.inner(), input.note.serial]); + let new_serial_blind = pallas::Scalar::random(&mut OsRng); let new_serial_commit = pedersen_commitment_base(new_serial, new_serial_blind); - let new_value_commit = pedersen_commitment_u64(value + REWARD, value_blind); + let new_value_commit = pedersen_commitment_u64(output.value, output.value_blind); + let new_value_pallas = pallas::Base::from(output.value); + let (new_pub_x, new_pub_y) = output.public_key.xy(); + + let new_coin = Coin::from(poseidon_hash([ + new_pub_x, + new_pub_y, + new_value_pallas, + PALLAS_ZERO, + new_serial, + output.coin_blind, + ])); + let slot_pallas = pallas::Base::from(slot_checkpoint.slot); - let seed = poseidon_hash([SEED_PREFIX, serial, PALLAS_ZERO]); + let seed = poseidon_hash([SEED_PREFIX, input.note.serial]); // NOTE: slot checkpoint eta to be renamed to previous_eta, // corresponding to previous block eta. let mut vrf_input = [0u8; 64]; vrf_input[..32].copy_from_slice(&slot_checkpoint.eta.to_repr()); vrf_input[32..].copy_from_slice(&slot_pallas.to_repr()); - let vrf_proof = VrfProof::prove(secret_key.into(), &vrf_input, &mut OsRng); + let vrf_proof = VrfProof::prove(input.secret, &vrf_input, &mut OsRng); let mut eta = [0u8; 64]; eta[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes()); let eta = pallas::Base::from_uniform_bytes(&eta); @@ -373,12 +293,16 @@ pub fn create_proposal_reward_proof( let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2); // Generate public inputs, witnesses and proof - let public_inputs = ConsensusProposalRewardRevealed { + let public_inputs = ConsensusProposalRevealed { nullifier, + epoch, public_key, + merkle_root, value_commit, + new_serial, new_serial_commit, new_value_commit, + new_coin, vrf_proof, mu_y, y, @@ -389,12 +313,20 @@ pub fn create_proposal_reward_proof( }; let prover_witnesses = vec![ - Witness::Base(Value::known(secret_key)), - Witness::Base(Value::known(serial)), - Witness::Base(Value::known(pallas::Base::from(value))), + Witness::Base(Value::known(input.secret.inner())), + Witness::Base(Value::known(input.note.serial)), + Witness::Base(Value::known(pallas::Base::from(input.note.value))), + Witness::Base(Value::known(epoch_pallas)), Witness::Base(Value::known(REWARD_PALLAS)), - Witness::Scalar(Value::known(value_blind)), + Witness::Scalar(Value::known(input.value_blind)), + Witness::Base(Value::known(input.note.coin_blind)), + Witness::Uint32(Value::known(u64::from(input.leaf_position).try_into().unwrap())), + Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())), Witness::Scalar(Value::known(new_serial_blind)), + Witness::Base(Value::known(new_pub_x)), + Witness::Base(Value::known(new_pub_y)), + Witness::Scalar(Value::known(output.value_blind)), + Witness::Base(Value::known(output.coin_blind)), Witness::Base(Value::known(mu_y)), Witness::Base(Value::known(mu_rho)), Witness::Base(Value::known(sigma1)), @@ -407,58 +339,3 @@ pub fn create_proposal_reward_proof( Ok((proof, public_inputs)) } - -#[allow(clippy::too_many_arguments)] -pub fn create_proposal_mint_proof( - zkbin: &ZkBinary, - pk: &ProvingKey, - output: &TransactionBuilderOutputInfo, - value_blind: pallas::Scalar, - token_blind: pallas::Scalar, - serial_blind: pallas::Scalar, - burnt_secret_key: pallas::Base, - burnt_serial: pallas::Base, - spend_hook: pallas::Base, - user_data: pallas::Base, - coin_blind: pallas::Base, -) -> Result<(Proof, ConsensusProposalMintRevealed, pallas::Base)> { - let serial = poseidon_hash([SERIAL_PREFIX, burnt_secret_key, burnt_serial, PALLAS_ZERO]); - let value_commit = pedersen_commitment_u64(output.value, value_blind); - let token_commit = pedersen_commitment_base(output.token_id.inner(), token_blind); - let serial_commit = pedersen_commitment_base(serial, serial_blind); - let (pub_x, pub_y) = output.public_key.xy(); - - let coin = Coin::from(poseidon_hash([ - pub_x, - pub_y, - pallas::Base::from(output.value), - output.token_id.inner(), - serial, - spend_hook, - user_data, - coin_blind, - ])); - - let public_inputs = - ConsensusProposalMintRevealed { coin, value_commit, token_commit, serial_commit }; - - let prover_witnesses = vec![ - Witness::Base(Value::known(pub_x)), - Witness::Base(Value::known(pub_y)), - Witness::Base(Value::known(pallas::Base::from(output.value))), - Witness::Base(Value::known(output.token_id.inner())), - Witness::Base(Value::known(burnt_secret_key)), - Witness::Base(Value::known(burnt_serial)), - Witness::Base(Value::known(coin_blind)), - Witness::Base(Value::known(spend_hook)), - Witness::Base(Value::known(user_data)), - Witness::Scalar(Value::known(value_blind)), - Witness::Scalar(Value::known(token_blind)), - Witness::Scalar(Value::known(serial_blind)), - ]; - - let circuit = ZkCircuit::new(prover_witnesses, zkbin.clone()); - let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?; - - Ok((proof, public_inputs, serial)) -} diff --git a/src/contract/consensus/src/client/proposal_v1_2.rs b/src/contract/consensus/src/client/proposal_v1_2.rs deleted file mode 100644 index 230da0d48..000000000 --- a/src/contract/consensus/src/client/proposal_v1_2.rs +++ /dev/null @@ -1,341 +0,0 @@ -/* This file is part of DarkFi (https://dark.fi) - * - * Copyright (C) 2020-2023 Dyne.org foundation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -//! This API is crufty. Please rework it into something nice to read and nice to use. - -use darkfi::{ - consensus::SlotCheckpoint, - zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit}, - zkas::ZkBinary, - Result, -}; -use darkfi_money_contract::{ - client::{ConsensusNote, ConsensusOwnCoin}, - model::{ConsensusInput, ConsensusOutput, PALLAS_ZERO}, -}; -use darkfi_sdk::{ - crypto::{ - ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base, - pedersen_commitment_u64, poseidon_hash, Coin, MerkleNode, MerkleTree, Nullifier, PublicKey, - SecretKey, - }, - incrementalmerkletree::{Hashable, Tree}, - pasta::{group::ff::FromUniformBytes, pallas}, -}; -use log::debug; -use rand::rngs::OsRng; - -use crate::{ - client::common::{ConsensusBurnInputInfo, ConsensusMintOutputInfo}, - model::{ - ConsensusProposalParamsV1, HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD, REWARD_PALLAS, - SEED_PREFIX, SERIAL_PREFIX, - }, -}; - -pub struct ConsensusProposalCallDebris { - pub params: ConsensusProposalParamsV1, - pub proofs: Vec, - pub signature_secret: SecretKey, -} - -pub struct ConsensusProposalRevealed { - pub nullifier: Nullifier, - pub epoch: u64, - pub public_key: PublicKey, - pub merkle_root: MerkleNode, - pub value_commit: pallas::Point, - pub new_serial: pallas::Base, - pub new_serial_commit: pallas::Point, - pub new_value_commit: pallas::Point, - pub new_coin: Coin, - pub vrf_proof: VrfProof, - pub mu_y: pallas::Base, - pub y: pallas::Base, - pub mu_rho: pallas::Base, - pub rho: pallas::Base, - pub sigma1: pallas::Base, - pub sigma2: pallas::Base, -} - -impl ConsensusProposalRevealed { - pub fn to_vec(&self) -> Vec { - let epoch_palas = pallas::Base::from(self.epoch); - let (pub_x, pub_y) = self.public_key.xy(); - let value_coords = self.value_commit.to_affine().coordinates().unwrap(); - let new_serial_coords = self.new_serial_commit.to_affine().coordinates().unwrap(); - let reward_pallas = pallas::Base::from(REWARD); - let new_value_coords = self.new_value_commit.to_affine().coordinates().unwrap(); - - // NOTE: It's important to keep these in the same order - // as the `constrain_instance` calls in the zkas code. - vec![ - self.nullifier.inner(), - epoch_palas, - pub_x, - pub_y, - self.merkle_root.inner(), - *value_coords.x(), - *value_coords.y(), - *new_serial_coords.x(), - *new_serial_coords.y(), - reward_pallas, - *new_value_coords.x(), - *new_value_coords.y(), - self.new_coin.inner(), - self.mu_y, - self.y, - self.mu_rho, - self.rho, - self.sigma1, - self.sigma2, - HEADSTART, - ] - } -} - -/// Struct holding necessary information to build a proposal transaction. -pub struct ConsensusProposalCallBuilder { - /// `ConsensusOwnCoin` we're given to use in this builder - pub coin: ConsensusOwnCoin, - /// Rewarded slot checkpoint - pub slot_checkpoint: SlotCheckpoint, - /// Merkle tree of coins used to create inclusion proofs - pub tree: MerkleTree, - /// `Proposal_V1` zkas circuit ZkBinary - pub proposal_zkbin: ZkBinary, - /// Proving key for the `Proposal_V1` zk circuit - pub proposal_pk: ProvingKey, -} - -impl ConsensusProposalCallBuilder { - pub fn build(&self) -> Result { - debug!("Building Consensus::ProposalBurnV1 contract call for proposal"); - let value = self.coin.note.value; - assert!(value != 0); - - debug!("Building Consensus::ProposalV1 anonymous input"); - let leaf_position = self.coin.leaf_position; - let root = self.tree.root(0).unwrap(); - let merkle_path = self.tree.authentication_path(leaf_position, &root).unwrap(); - let input = ConsensusBurnInputInfo { - leaf_position, - merkle_path, - secret: self.coin.secret, - note: self.coin.note.clone(), - value_blind: pallas::Scalar::random(&mut OsRng), - }; - - debug!("Building anonymous output"); - let reward_blind = pallas::Scalar::random(&mut OsRng); - let new_value_blind = input.value_blind + reward_blind; - let new_coin_blind = pallas::Base::random(&mut OsRng); - let output = ConsensusMintOutputInfo { - value: self.coin.note.value + REWARD, - epoch: 0, - public_key: PublicKey::from_secret(self.coin.secret), - value_blind: new_value_blind, - serial: self.coin.note.serial, - coin_blind: new_coin_blind, - }; - debug!("Finished building output"); - - debug!("Building Consensus::ProposalV1 contract call for proposal"); - let (proof, public_inputs) = create_proposal_proof( - &self.proposal_zkbin, - &self.proposal_pk, - &input, - &output, - &self.slot_checkpoint, - )?; - - let input = ConsensusInput { - epoch: self.coin.note.epoch, - value_commit: public_inputs.value_commit, - nullifier: public_inputs.nullifier, - merkle_root: public_inputs.merkle_root, - signature_public: public_inputs.public_key, - }; - - // Encrypted note - let note = ConsensusNote { - serial: public_inputs.new_serial, - value: output.value, - epoch: 0, - coin_blind: new_coin_blind, - value_blind: new_value_blind, - reward: REWARD, - reward_blind, - }; - - let encrypted_note = AeadEncryptedNote::encrypt(¬e, &output.public_key, &mut OsRng)?; - - let output = ConsensusOutput { - value_commit: public_inputs.new_value_commit, - coin: public_inputs.new_coin, - note: encrypted_note, - }; - - // We now fill this with necessary stuff - let new_serial_commit = public_inputs.new_serial_commit; - let slot = self.slot_checkpoint.slot; - let vrf_proof = public_inputs.vrf_proof; - let y = public_inputs.y; - let rho = public_inputs.rho; - let params = ConsensusProposalParamsV1 { - input, - output, - reward: REWARD, - reward_blind, - new_serial_commit, - slot, - vrf_proof, - y, - rho, - }; - let proofs = vec![proof]; - - // Now we should have all the params, zk proofs and signature secret. - // We return it all and let the caller deal with it. - let debris = - ConsensusProposalCallDebris { params, proofs, signature_secret: self.coin.secret }; - Ok(debris) - } -} - -pub fn create_proposal_proof( - zkbin: &ZkBinary, - pk: &ProvingKey, - input: &ConsensusBurnInputInfo, - output: &ConsensusMintOutputInfo, - slot_checkpoint: &SlotCheckpoint, -) -> Result<(Proof, ConsensusProposalRevealed)> { - // Proof parameters - let nullifier = Nullifier::from(poseidon_hash([input.secret.inner(), input.note.serial])); - let epoch = input.note.epoch; - let epoch_pallas = pallas::Base::from(epoch); - let value_pallas = pallas::Base::from(input.note.value); - let value_commit = pedersen_commitment_u64(input.note.value, input.value_blind); - let public_key = PublicKey::from_secret(input.secret); - let (pub_x, pub_y) = public_key.xy(); - - // Burnt coin and its merkle_root - let coin = poseidon_hash([ - pub_x, - pub_y, - value_pallas, - epoch_pallas, - input.note.serial, - input.note.coin_blind, - ]); - - let merkle_root = { - let position: u64 = input.leaf_position.into(); - let mut current = MerkleNode::from(coin); - for (level, sibling) in input.merkle_path.iter().enumerate() { - let level = level as u8; - current = if position & (1 << level) == 0 { - MerkleNode::combine(level.into(), ¤t, sibling) - } else { - MerkleNode::combine(level.into(), sibling, ¤t) - }; - } - current - }; - - // New coin - let new_serial = poseidon_hash([SERIAL_PREFIX, input.secret.inner(), input.note.serial]); - let new_serial_blind = pallas::Scalar::random(&mut OsRng); - let new_serial_commit = pedersen_commitment_base(new_serial, new_serial_blind); - let new_value_commit = pedersen_commitment_u64(output.value, output.value_blind); - let new_value_pallas = pallas::Base::from(output.value); - let (new_pub_x, new_pub_y) = output.public_key.xy(); - - let new_coin = Coin::from(poseidon_hash([ - new_pub_x, - new_pub_y, - new_value_pallas, - PALLAS_ZERO, - new_serial, - output.coin_blind, - ])); - - let slot_pallas = pallas::Base::from(slot_checkpoint.slot); - let seed = poseidon_hash([SEED_PREFIX, input.note.serial]); - // NOTE: slot checkpoint eta to be renamed to previous_eta, - // corresponding to previous block eta. - let mut vrf_input = [0u8; 64]; - vrf_input[..32].copy_from_slice(&slot_checkpoint.eta.to_repr()); - vrf_input[32..].copy_from_slice(&slot_pallas.to_repr()); - let vrf_proof = VrfProof::prove(input.secret.into(), &vrf_input, &mut OsRng); - let mut eta = [0u8; 64]; - eta[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes()); - let eta = pallas::Base::from_uniform_bytes(&eta); - let mu_y = poseidon_hash([MU_Y_PREFIX, eta, slot_pallas]); - let y = poseidon_hash([seed, mu_y]); - let mu_rho = poseidon_hash([MU_RHO_PREFIX, eta, slot_pallas]); - let rho = poseidon_hash([seed, mu_rho]); - let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2); - - // Generate public inputs, witnesses and proof - let public_inputs = ConsensusProposalRevealed { - nullifier, - epoch, - public_key, - merkle_root, - value_commit, - new_serial, - new_serial_commit, - new_value_commit, - new_coin, - vrf_proof, - mu_y, - y, - mu_rho, - rho, - sigma1, - sigma2, - }; - - let prover_witnesses = vec![ - Witness::Base(Value::known(input.secret.inner())), - Witness::Base(Value::known(input.note.serial)), - Witness::Base(Value::known(pallas::Base::from(input.note.value))), - Witness::Base(Value::known(epoch_pallas)), - Witness::Base(Value::known(REWARD_PALLAS)), - Witness::Scalar(Value::known(input.value_blind)), - Witness::Base(Value::known(input.note.coin_blind)), - Witness::Uint32(Value::known(u64::from(input.leaf_position).try_into().unwrap())), - Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())), - Witness::Scalar(Value::known(new_serial_blind)), - Witness::Base(Value::known(new_pub_x)), - Witness::Base(Value::known(new_pub_y)), - Witness::Scalar(Value::known(output.value_blind)), - Witness::Base(Value::known(output.coin_blind)), - Witness::Base(Value::known(mu_y)), - Witness::Base(Value::known(mu_rho)), - Witness::Base(Value::known(sigma1)), - Witness::Base(Value::known(sigma2)), - Witness::Base(Value::known(HEADSTART)), - ]; - - let circuit = ZkCircuit::new(prover_witnesses, zkbin.clone()); - let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?; - - Ok((proof, public_inputs)) -} diff --git a/src/contract/consensus/src/entrypoint.rs b/src/contract/consensus/src/entrypoint.rs index f3d2d15ee..b1d475721 100644 --- a/src/contract/consensus/src/entrypoint.rs +++ b/src/contract/consensus/src/entrypoint.rs @@ -32,10 +32,7 @@ use darkfi_sdk::{ }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; -use crate::{ - model::{ConsensusProposalRewardUpdateV1, ConsensusProposalUpdateV1}, - ConsensusFunction, -}; +use crate::{model::ConsensusProposalUpdateV1, ConsensusFunction}; /// `Consensus::GenesisStake` functions mod genesis_stake_v1; @@ -50,27 +47,6 @@ use stake_v1::{ consensus_stake_process_update_v1, }; -/// `Consensus::ProposalBurn` functions -mod proposal_burn_v1; -use proposal_burn_v1::{ - consensus_proposal_burn_get_metadata_v1, consensus_proposal_burn_process_instruction_v1, - consensus_proposal_burn_process_update_v1, -}; - -/// `Consensus::ProposalRewardV1` functions -mod proposal_reward_v1; -use proposal_reward_v1::{ - consensus_proposal_reward_get_metadata_v1, consensus_proposal_reward_process_instruction_v1, - consensus_proposal_reward_process_update_v1, -}; - -/// `Consensus::ProposalMintV1` functions -mod proposal_mint_v1; -use proposal_mint_v1::{ - consensus_proposal_mint_get_metadata_v1, consensus_proposal_mint_process_instruction_v1, - consensus_proposal_mint_process_update_v1, -}; - /// `Consensus::ProposalV1` functions mod proposal_v1; use proposal_v1::{ @@ -101,21 +77,13 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult { // respective db functions. The special `zkas db` operations exist in // order to be able to verify the circuits being bundled and enforcing // a specific tree inside sled, and also creation of VerifyingKey. - let money_mint_v1_bincode = include_bytes!("../../money/proof/mint_v1.zk.bin"); - let money_burn_v1_bincode = include_bytes!("../../money/proof/burn_v1.zk.bin"); let consensus_mint_v1_bincode = include_bytes!("../proof/consensus_mint_v1.zk.bin"); let consensus_burn_v1_bincode = include_bytes!("../proof/consensus_burn_v1.zk.bin"); - let proposal_reward_v1_bincode = include_bytes!("../proof/proposal_reward_v1.zk.bin"); - let proposal_mint_v1_bincode = include_bytes!("../proof/proposal_mint_v1.zk.bin"); let consensus_proposal_v1_bincode = include_bytes!("../proof/consensus_proposal_v1.zk.bin"); // For that, we use `zkas_db_set` and pass in the bincode. - zkas_db_set(&money_mint_v1_bincode[..])?; - zkas_db_set(&money_burn_v1_bincode[..])?; zkas_db_set(&consensus_mint_v1_bincode[..])?; zkas_db_set(&consensus_burn_v1_bincode[..])?; - zkas_db_set(&proposal_reward_v1_bincode[..])?; - zkas_db_set(&proposal_mint_v1_bincode[..])?; zkas_db_set(&consensus_proposal_v1_bincode[..])?; // Set up a database tree to hold Merkle roots of all coins @@ -187,18 +155,6 @@ fn get_metadata(cid: ContractId, ix: &[u8]) -> ContractResult { let metadata = consensus_stake_get_metadata_v1(cid, call_idx, calls)?; Ok(set_return_data(&metadata)?) } - ConsensusFunction::ProposalBurnV1 => { - let metadata = consensus_proposal_burn_get_metadata_v1(cid, call_idx, calls)?; - Ok(set_return_data(&metadata)?) - } - ConsensusFunction::ProposalRewardV1 => { - let metadata = consensus_proposal_reward_get_metadata_v1(cid, call_idx, calls)?; - Ok(set_return_data(&metadata)?) - } - ConsensusFunction::ProposalMintV1 => { - let metadata = consensus_proposal_mint_get_metadata_v1(cid, call_idx, calls)?; - Ok(set_return_data(&metadata)?) - } ConsensusFunction::ProposalV1 => { let metadata = consensus_proposal_get_metadata_v1(cid, call_idx, calls)?; Ok(set_return_data(&metadata)?) @@ -234,19 +190,6 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult { let update_data = consensus_stake_process_instruction_v1(cid, call_idx, calls)?; Ok(set_return_data(&update_data)?) } - ConsensusFunction::ProposalBurnV1 => { - let update_data = consensus_proposal_burn_process_instruction_v1(cid, call_idx, calls)?; - Ok(set_return_data(&update_data)?) - } - ConsensusFunction::ProposalRewardV1 => { - let update_data = - consensus_proposal_reward_process_instruction_v1(cid, call_idx, calls)?; - Ok(set_return_data(&update_data)?) - } - ConsensusFunction::ProposalMintV1 => { - let update_data = consensus_proposal_mint_process_instruction_v1(cid, call_idx, calls)?; - Ok(set_return_data(&update_data)?) - } ConsensusFunction::ProposalV1 => { let update_data = consensus_proposal_process_instruction_v1(cid, call_idx, calls)?; Ok(set_return_data(&update_data)?) @@ -273,18 +216,6 @@ fn process_update(cid: ContractId, update_data: &[u8]) -> ContractResult { let update: ConsensusStakeUpdateV1 = deserialize(&update_data[1..])?; Ok(consensus_stake_process_update_v1(cid, update)?) } - ConsensusFunction::ProposalBurnV1 => { - let update: ConsensusUnstakeUpdateV1 = deserialize(&update_data[1..])?; - Ok(consensus_proposal_burn_process_update_v1(cid, update)?) - } - ConsensusFunction::ProposalRewardV1 => { - let update: ConsensusProposalRewardUpdateV1 = deserialize(&update_data[1..])?; - Ok(consensus_proposal_reward_process_update_v1(cid, update)?) - } - ConsensusFunction::ProposalMintV1 => { - let update: ConsensusStakeUpdateV1 = deserialize(&update_data[1..])?; - Ok(consensus_proposal_mint_process_update_v1(cid, update)?) - } ConsensusFunction::ProposalV1 => { let update: ConsensusProposalUpdateV1 = deserialize(&update_data[1..])?; Ok(consensus_proposal_process_update_v1(cid, update)?) diff --git a/src/contract/consensus/src/entrypoint/proposal_burn_v1.rs b/src/contract/consensus/src/entrypoint/proposal_burn_v1.rs deleted file mode 100644 index f09a99fe8..000000000 --- a/src/contract/consensus/src/entrypoint/proposal_burn_v1.rs +++ /dev/null @@ -1,189 +0,0 @@ -/* This file is part of DarkFi (https://dark.fi) - * - * Copyright (C) 2020-2023 Dyne.org foundation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -use darkfi_money_contract::{ - error::MoneyError, - model::{ConsensusUnstakeUpdateV1, PALLAS_ZERO}, - CONSENSUS_CONTRACT_COIN_ROOTS_TREE, CONSENSUS_CONTRACT_NULLIFIERS_TREE, - MONEY_CONTRACT_ZKAS_BURN_NS_V1, -}; -use darkfi_sdk::{ - crypto::{ - pasta_prelude::*, pedersen_commitment_base, ContractId, CONSENSUS_CONTRACT_ID, - DARK_TOKEN_ID, - }, - db::{db_contains_key, db_lookup, db_set}, - error::{ContractError, ContractResult}, - msg, - pasta::pallas, - ContractCall, -}; -use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; - -use crate::{ - model::{ConsensusProposalBurnParamsV1, ConsensusProposalRewardParamsV1}, - ConsensusFunction, -}; - -/// `get_metadata` function for `Consensus::ProposalBurnV1` -pub(crate) fn consensus_proposal_burn_get_metadata_v1( - _cid: ContractId, - call_idx: u32, - calls: Vec, -) -> Result, ContractError> { - let self_ = &calls[call_idx as usize]; - let params: ConsensusProposalBurnParamsV1 = deserialize(&self_.data[1..])?; - let input = ¶ms.input; - - // Public inputs for the ZK proofs we have to verify - let mut zk_public_inputs: Vec<(String, Vec)> = vec![]; - // 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 - // anonymous input - let value_coords = input.value_commit.to_affine().coordinates().unwrap(); - let token_coords = input.token_commit.to_affine().coordinates().unwrap(); - let (sig_x, sig_y) = input.signature_public.xy(); - - // It is very important that these are in the same order as the - // `constrain_instance` calls in the zkas code. - // Otherwise verification will fail. - zk_public_inputs.push(( - MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string(), - vec![ - input.nullifier.inner(), - *value_coords.x(), - *value_coords.y(), - *token_coords.x(), - *token_coords.y(), - input.merkle_root.inner(), - input.user_data_enc, - sig_x, - sig_y, - ], - )); - - // Serialize everything gathered and return it - let mut metadata = vec![]; - zk_public_inputs.encode(&mut metadata)?; - signature_pubkeys.encode(&mut metadata)?; - - Ok(metadata) -} - -/// `process_instruction` function for `Consensus::ProposalBurnV1` -pub(crate) fn consensus_proposal_burn_process_instruction_v1( - cid: ContractId, - call_idx: u32, - calls: Vec, -) -> Result, ContractError> { - let self_ = &calls[call_idx as usize]; - let params: ConsensusProposalBurnParamsV1 = deserialize(&self_.data[1..])?; - - // Access the necessary databases where there is information to - // validate this state transition. - let nullifiers_db = db_lookup(cid, CONSENSUS_CONTRACT_NULLIFIERS_TREE)?; - let coin_roots_db = db_lookup(cid, CONSENSUS_CONTRACT_COIN_ROOTS_TREE)?; - - // =================================== - // Perform the actual state transition - // =================================== - - msg!("[ConsensusProposalBurnV1] Validating anonymous input"); - let input = ¶ms.input; - - // Only native token can be burned in a proposal - if input.token_commit != pedersen_commitment_base(DARK_TOKEN_ID.inner(), params.token_blind) { - msg!("[ConsensusProposalBurnV1] Error: Input used non-native token"); - return Err(MoneyError::StakeInputNonNativeToken.into()) - } - - // The Merkle root is used to know whether this is a coin that - // existed in a previous state. - if !db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? { - msg!("[ConsensusProposalBurnV1] 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!("[ConsensusProposalBurnV1] Error: Duplicate nullifier found"); - return Err(MoneyError::DuplicateNullifier.into()) - } - - // Check next call is consensus contract - let next_call_idx = call_idx + 1; - if next_call_idx >= calls.len() as u32 { - msg!("[ConsensusProposalBurnV1] 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() != CONSENSUS_CONTRACT_ID.inner() { - msg!("[ConsensusProposalBurnV1] Error: Next contract call is not consensus contract"); - return Err(MoneyError::StakeNextCallNotConsensusContract.into()) - } - - // Check if spend hook is set and its correctness - if input.spend_hook == PALLAS_ZERO { - msg!("[ConsensusProposalBurnV1] Error: Missing spend hook"); - return Err(MoneyError::StakeMissingSpendHook.into()) - } - - if input.spend_hook != CONSENSUS_CONTRACT_ID.inner() { - msg!("[ConsensusProposalBurnV1] Error: Spend hook is not consensus contract"); - return Err(MoneyError::UnstakeSpendHookNotConsensusContract.into()) - } - - // Verify next call corresponds to Consensus::ProposalRewardV1 (0x03) - if next.data[0] != 0x03 { - msg!("[ConsensusProposalBurnV1] Error: Next call function mismatch"); - return Err(MoneyError::NextCallFunctionMissmatch.into()) - } - - // Verify next call StakeInput is the same as this calls input - let next_params: ConsensusProposalRewardParamsV1 = deserialize(&next.data[1..])?; - if input != &next_params.burnt_input || params.public_key != next_params.burnt_public_key { - msg!("[ConsensusProposalBurnV1] Error: Next call input mismatch"); - return Err(MoneyError::NextCallInputMissmatch.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) -} - -/// `process_update` function for `Consensus::ProposalBurnV1` -pub(crate) fn consensus_proposal_burn_process_update_v1( - cid: ContractId, - update: ConsensusUnstakeUpdateV1, -) -> ContractResult { - // Grab all necessary db handles for where we want to write - let nullifiers_db = db_lookup(cid, CONSENSUS_CONTRACT_NULLIFIERS_TREE)?; - - msg!("[ConsensusProposalBurnV1] Adding new nullifier to the set"); - db_set(nullifiers_db, &serialize(&update.nullifier), &[])?; - - Ok(()) -} diff --git a/src/contract/consensus/src/entrypoint/proposal_mint_v1.rs b/src/contract/consensus/src/entrypoint/proposal_mint_v1.rs deleted file mode 100644 index e47534b3c..000000000 --- a/src/contract/consensus/src/entrypoint/proposal_mint_v1.rs +++ /dev/null @@ -1,205 +0,0 @@ -/* This file is part of DarkFi (https://dark.fi) - * - * Copyright (C) 2020-2023 Dyne.org foundation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -use darkfi_money_contract::{ - error::MoneyError, - model::{ConsensusStakeUpdateV1, PALLAS_ZERO}, - CONSENSUS_CONTRACT_COINS_TREE, CONSENSUS_CONTRACT_COIN_MERKLE_TREE, - CONSENSUS_CONTRACT_COIN_ROOTS_TREE, CONSENSUS_CONTRACT_INFO_TREE, - CONSENSUS_CONTRACT_NULLIFIERS_TREE, CONSENSUS_CONTRACT_ZKAS_PROPOSAL_MINT_NS_V1, -}; -use darkfi_sdk::{ - crypto::{pasta_prelude::*, ContractId, MerkleNode, CONSENSUS_CONTRACT_ID}, - db::{db_contains_key, db_lookup, db_set}, - error::{ContractError, ContractResult}, - merkle_add, msg, - pasta::pallas, - ContractCall, -}; -use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; - -use crate::{ - model::{ConsensusProposalMintParamsV1, ConsensusProposalRewardParamsV1}, - ConsensusFunction, -}; - -/// `get_metadata` function for `Consensus::ProposalMintV1` -pub(crate) fn consensus_proposal_mint_get_metadata_v1( - _cid: ContractId, - call_idx: u32, - calls: Vec, -) -> Result, ContractError> { - let self_ = &calls[call_idx as usize]; - let params: ConsensusProposalMintParamsV1 = deserialize(&self_.data[1..])?; - - // Public inputs for the ZK proofs we have to verify - let mut zk_public_inputs: Vec<(String, Vec)> = vec![]; - // Public keys for the transaction signatures we have to verify - let signature_pubkeys = vec![params.input.signature_public]; - - // Grab the pedersen commitment from the anonymous output - let output = ¶ms.output; - let value_coords = output.value_commit.to_affine().coordinates().unwrap(); - let token_coords = output.token_commit.to_affine().coordinates().unwrap(); - let serial_coords = ¶ms.serial_commit.to_affine().coordinates().unwrap(); - - zk_public_inputs.push(( - CONSENSUS_CONTRACT_ZKAS_PROPOSAL_MINT_NS_V1.to_string(), - vec![ - output.coin.inner(), - *value_coords.x(), - *value_coords.y(), - *token_coords.x(), - *token_coords.y(), - *serial_coords.x(), - *serial_coords.y(), - ], - )); - - // Serialize everything gathered and return it - let mut metadata = vec![]; - zk_public_inputs.encode(&mut metadata)?; - signature_pubkeys.encode(&mut metadata)?; - - Ok(metadata) -} - -/// `process_instruction` function for `Consensus::ProposalMintV1` -pub(crate) fn consensus_proposal_mint_process_instruction_v1( - cid: ContractId, - call_idx: u32, - calls: Vec, -) -> Result, ContractError> { - let self_ = &calls[call_idx as usize]; - let params: ConsensusProposalMintParamsV1 = deserialize(&self_.data[1..])?; - - // Access the necessary databases where there is information to - // validate this state transition. - let coins_db = db_lookup(cid, CONSENSUS_CONTRACT_COINS_TREE)?; - let nullifiers_db = db_lookup(cid, CONSENSUS_CONTRACT_NULLIFIERS_TREE)?; - let coin_roots_db = db_lookup(cid, CONSENSUS_CONTRACT_COIN_ROOTS_TREE)?; - - // =================================== - // Perform the actual state transition - // =================================== - - msg!("[ConsensusProposalMintV1] Validating anonymous output"); - let input = ¶ms.input; - let output = ¶ms.output; - - /* - // Only native token can be minted in a proposal - if output.token_commit != pedersen_commitment_base(DARK_TOKEN_ID.inner(), input.token_blind) { - msg!("[ConsensusProposalMintV1] Error: Input used non-native token"); - return Err(MoneyError::StakeInputNonNativeToken.into()) - } - */ - - // Verify value commits match - if output.value_commit != input.value_commit { - msg!("[ConsensusProposalMintV1] Error: Value commitments do not match"); - return Err(MoneyError::ValueMismatch.into()) - } - - // The Merkle root is used to know whether this is a coin that - // existed in a previous state. - if !db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? { - msg!("[ConsensusProposalMintV1] Error: Merkle root not found in previous state"); - return Err(MoneyError::TransferMerkleRootNotFound.into()) - } - - // The nullifiers should already exist. It is the double-mint protection. - if db_contains_key(nullifiers_db, &serialize(&input.nullifier))? { - msg!("[ConsensusProposalMintV1] Error: Missing nullifier"); - return Err(MoneyError::StakeMissingNullifier.into()) - } - - // Check previous call is consensus contract - if call_idx == 0 { - msg!("[ConsensusProposalMintV1] Error: previous_call_idx will be out of bounds"); - return Err(MoneyError::SpendHookOutOfBounds.into()) - } - - let previous_call_idx = call_idx - 1; - let previous = &calls[previous_call_idx as usize]; - if previous.contract_id.inner() != CONSENSUS_CONTRACT_ID.inner() { - msg!("[ConsensusProposalMintV1] Error: Previous contract call is not consensus contract"); - return Err(MoneyError::UnstakePreviousCallNotConsensusContract.into()) - } - - // Verify previous call corresponds to Consensus::ProposalRewardV1 (0x03) - if previous.data[0] != 0x03 { - msg!("[ConsensusProposalMintV1] Error: Previous call function mismatch"); - return Err(MoneyError::PreviousCallFunctionMissmatch.into()) - } - - // Verify previous call input is the same as this calls StakeInput - let previous_params: ConsensusProposalRewardParamsV1 = deserialize(&previous.data[1..])?; - let previous_input = &previous_params.mint_input; - if previous_input != input || - &previous_params.output != output || - previous_params.new_serial_commit != params.serial_commit - { - msg!("[ConsensusProposalMintV1] Error: Previous call input mismatch"); - return Err(MoneyError::PreviousCallInputMissmatch.into()) - } - - // If spend hook is set, check its correctness - let previous_input = &previous_params.burnt_input; - if previous_input.spend_hook != PALLAS_ZERO && - previous_input.spend_hook != CONSENSUS_CONTRACT_ID.inner() - { - msg!("[ConsensusProposalMintV1] Error: Invoking contract call does not match spend hook in input"); - return Err(MoneyError::SpendHookMismatch.into()) - } - - // Newly created coin for this call is in the output. Here we gather it, - // and we also check that it hasn't existed before. - if db_contains_key(coins_db, &serialize(&output.coin))? { - msg!("[ConsensusProposalMintV1] Error: Duplicate coin found in output"); - return Err(MoneyError::DuplicateCoin.into()) - } - - // Create a state update. - let update = ConsensusStakeUpdateV1 { coin: output.coin }; - let mut update_data = vec![]; - update_data.write_u8(ConsensusFunction::StakeV1 as u8)?; - update.encode(&mut update_data)?; - - Ok(update_data) -} - -/// `process_update` function for `Consensus::ProposalMintV1` -pub(crate) fn consensus_proposal_mint_process_update_v1( - cid: ContractId, - update: ConsensusStakeUpdateV1, -) -> ContractResult { - // Grab all necessary db handles for where we want to write - let info_db = db_lookup(cid, CONSENSUS_CONTRACT_INFO_TREE)?; - let coins_db = db_lookup(cid, CONSENSUS_CONTRACT_COINS_TREE)?; - let coin_roots_db = db_lookup(cid, CONSENSUS_CONTRACT_COIN_ROOTS_TREE)?; - - msg!("[ConsensusProposalMintV1] Adding new coin to the set"); - db_set(coins_db, &serialize(&update.coin), &[])?; - - msg!("[ConsensusProposalMintV1] Adding new coin to the Merkle tree"); - let coins: Vec<_> = vec![MerkleNode::from(update.coin.inner())]; - merkle_add(info_db, coin_roots_db, &serialize(&CONSENSUS_CONTRACT_COIN_MERKLE_TREE), &coins)?; - - Ok(()) -} diff --git a/src/contract/consensus/src/entrypoint/proposal_reward_v1.rs b/src/contract/consensus/src/entrypoint/proposal_reward_v1.rs deleted file mode 100644 index 8fe1bffb1..000000000 --- a/src/contract/consensus/src/entrypoint/proposal_reward_v1.rs +++ /dev/null @@ -1,255 +0,0 @@ -/* This file is part of DarkFi (https://dark.fi) - * - * Copyright (C) 2020-2023 Dyne.org foundation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -use darkfi_money_contract::{ - error::MoneyError, model::PALLAS_ZERO, CONSENSUS_CONTRACT_ZKAS_PROPOSAL_REWARD_NS_V1, -}; -use darkfi_sdk::{ - crypto::{ - pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, CONSENSUS_CONTRACT_ID, - }, - error::{ContractError, ContractResult}, - msg, - pasta::{group::ff::FromUniformBytes, pallas}, - util::get_slot_checkpoint, - ContractCall, -}; -use darkfi_serial::{deserialize, Encodable, WriteExt}; - -use crate::{ - error::ConsensusError, - model::{ - ConsensusProposalBurnParamsV1, ConsensusProposalMintParamsV1, - ConsensusProposalRewardParamsV1, ConsensusProposalRewardUpdateV1, SlotCheckpoint, - HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD, - }, - ConsensusFunction, -}; - -/// `get_metadata` function for `Consensus::ProposalRewardV1` -pub(crate) fn consensus_proposal_reward_get_metadata_v1( - _cid: ContractId, - call_idx: u32, - calls: Vec, -) -> Result, ContractError> { - let self_ = &calls[call_idx as usize]; - let params: ConsensusProposalRewardParamsV1 = deserialize(&self_.data[1..])?; - - // Public inputs for the ZK proofs we have to verify - let mut zk_public_inputs: Vec<(String, Vec)> = vec![]; - // Public keys for the transaction signatures we have to verify - let signature_pubkeys = vec![params.mint_input.signature_public]; - - // Grab the nullifier for the burnt coin - let nullifier = ¶ms.burnt_input.nullifier; - - // Grab the public key coordinates for the burnt coin - let (pub_x, pub_y) = ¶ms.burnt_public_key.xy(); - - // Grab the pedersen commitment for the burnt value - let value_coords = ¶ms.burnt_input.value_commit.to_affine().coordinates().unwrap(); - - // Grab the pedersen commitment for the minted serial number - let new_serial_coords = ¶ms.new_serial_commit.to_affine().coordinates().unwrap(); - - // Grab the pedersen commitment for the minted value - let new_value_coords = ¶ms.mint_input.value_commit.to_affine().coordinates().unwrap(); - - // Grab proposal coin y and rho for lottery - let y = ¶ms.y; - let rho = ¶ms.rho; - - // Grab the slot checkpoint to validate consensus parameters against - let slot = ¶ms.slot; - let Some(slot_checkpoint) = get_slot_checkpoint(*slot)? else { - msg!("[ConsensusProposalRewardV1] Error: Missing slot checkpoint {} from db", slot); - return Err(ConsensusError::ProposalMissingSlotCheckpoint.into()) - }; - let slot_checkpoint: SlotCheckpoint = deserialize(&slot_checkpoint)?; - - // Verify eta VRF proof - let slot_pallas = pallas::Base::from(slot_checkpoint.slot); - // NOTE: slot checkpoint eta to be renamed to previous_eta, - // corresponding to previous block eta. - let mut vrf_input = [0u8; 64]; - vrf_input[..32].copy_from_slice(&slot_checkpoint.eta.to_repr()); - vrf_input[32..].copy_from_slice(&slot_pallas.to_repr()); - let vrf_proof = ¶ms.vrf_proof; - if !vrf_proof.verify(params.burnt_public_key, &vrf_input) { - msg!("[ConsensusProposalRewardV1] Error: eta VRF proof couldn't be verified"); - return Err(ConsensusError::ProposalErroneousVrfProof.into()) - } - let mut eta = [0u8; 64]; - eta[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes()); - let eta = pallas::Base::from_uniform_bytes(&eta); - - // Calculate election seeds - let mu_y = poseidon_hash([MU_Y_PREFIX, eta, slot_pallas]); - let mu_rho = poseidon_hash([MU_RHO_PREFIX, eta, slot_pallas]); - - // Grab sigmas from slot checkpoint - let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2); - - zk_public_inputs.push(( - CONSENSUS_CONTRACT_ZKAS_PROPOSAL_REWARD_NS_V1.to_string(), - vec![ - nullifier.inner(), - *pub_x, - *pub_y, - *value_coords.x(), - *value_coords.y(), - *new_serial_coords.x(), - *new_serial_coords.y(), - *new_value_coords.x(), - *new_value_coords.y(), - mu_y, - *y, - mu_rho, - *rho, - sigma1, - sigma2, - HEADSTART, - ], - )); - - // Serialize everything gathered and return it - let mut metadata = vec![]; - zk_public_inputs.encode(&mut metadata)?; - signature_pubkeys.encode(&mut metadata)?; - - Ok(metadata) -} - -/// `process_instruction` function for `Consensus::ProposalRewardV1` -pub(crate) fn consensus_proposal_reward_process_instruction_v1( - _cid: ContractId, - call_idx: u32, - calls: Vec, -) -> Result, ContractError> { - let self_ = &calls[call_idx as usize]; - let params: ConsensusProposalRewardParamsV1 = deserialize(&self_.data[1..])?; - - // =================================== - // Perform the actual state transition - // =================================== - - msg!("[ConsensusProposalRewardV1] Validating anonymous inputs"); - let burnt_input = ¶ms.burnt_input; - let mint_input = ¶ms.mint_input; - let output = ¶ms.output; - - /* - // Only native token can be rewarded in a proposal - let dark_token_commit = pedersen_commitment_base(DARK_TOKEN_ID.inner(), mint_input.token_blind); - if burnt_input.token_commit != dark_token_commit || output.token_commit != dark_token_commit { - msg!("[ConsensusProposalRewardV1] Error: Input used non-native token"); - return Err(MoneyError::StakeInputNonNativeToken.into()) - } - */ - - // Verify value commits match - let mut valcom_total = pallas::Point::identity(); - valcom_total += burnt_input.value_commit; - valcom_total += pedersen_commitment_u64(REWARD, pallas::Scalar::zero()); - valcom_total -= mint_input.value_commit; - if valcom_total != pallas::Point::identity() { - msg!("[ConsensusProposalRewardV1] Error: Value commitments do not result in identity"); - return Err(MoneyError::ValueMismatch.into()) - } - - // Check previous call is consensus contract - if call_idx == 0 { - msg!("[ConsensusProposalRewardV1] Error: previous_call_idx will be out of bounds"); - return Err(MoneyError::SpendHookOutOfBounds.into()) - } - - let previous_call_idx = call_idx - 1; - let previous = &calls[previous_call_idx as usize]; - if previous.contract_id.inner() != CONSENSUS_CONTRACT_ID.inner() { - msg!("[ConsensusProposalRewardV1] Error: Previous contract call is not consensus contract"); - return Err(MoneyError::UnstakePreviousCallNotConsensusContract.into()) - } - - // Verify previous call corresponds to Consensus::ProposalBurnV1 (0x02) - if previous.data[0] != 0x02 { - msg!("[ConsensusProposalRewardV1] Error: Previous call function mismatch"); - return Err(MoneyError::PreviousCallFunctionMissmatch.into()) - } - - // Verify previous call input is the same as this calls StakeInput - let previous_params: ConsensusProposalBurnParamsV1 = deserialize(&previous.data[1..])?; - let previous_input = &previous_params.input; - if previous_input != burnt_input || previous_params.public_key != params.burnt_public_key { - msg!("[ConsensusProposalRewardV1] Error: Previous call input mismatch"); - return Err(MoneyError::PreviousCallInputMissmatch.into()) - } - - // If spend hook is set, check its correctness - if previous_input.spend_hook != PALLAS_ZERO && - previous_input.spend_hook != CONSENSUS_CONTRACT_ID.inner() - { - msg!("[ConsensusProposalRewardV1] Error: Invoking contract call does not match spend hook in input"); - return Err(MoneyError::SpendHookMismatch.into()) - } - - // Check next call is consensus contract - let next_call_idx = call_idx + 1; - if next_call_idx >= calls.len() as u32 { - msg!("[ConsensusProposalRewardV1] 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() != CONSENSUS_CONTRACT_ID.inner() { - msg!("[ConsensusProposalRewardV1] Error: Next contract call is not consensus contract"); - return Err(MoneyError::StakeNextCallNotConsensusContract.into()) - } - - // Verify next call corresponds to Consensus::ProposalMintV1 (0x04) - if next.data[0] != 0x04 { - msg!("[ConsensusProposalRewardV1] Error: Next call function mismatch"); - return Err(MoneyError::NextCallFunctionMissmatch.into()) - } - - // Verify next call StakeInput is the same as this calls input - let next_params: ConsensusProposalMintParamsV1 = deserialize(&next.data[1..])?; - if mint_input != &next_params.input || - output != &next_params.output || - params.new_serial_commit != next_params.serial_commit - { - msg!("[ConsensusProposalRewardV1] Error: Next call input mismatch"); - return Err(MoneyError::NextCallInputMissmatch.into()) - } - - // Create a state update. - let update = ConsensusProposalRewardUpdateV1 {}; - let mut update_data = vec![]; - update_data.write_u8(ConsensusFunction::ProposalRewardV1 as u8)?; - update.encode(&mut update_data)?; - - Ok(update_data) -} - -/// `process_update` function for `Consensus::ProposalRewardV1` -pub(crate) fn consensus_proposal_reward_process_update_v1( - _cid: ContractId, - _update: ConsensusProposalRewardUpdateV1, -) -> ContractResult { - // This contract call doesn't produce any updates - Ok(()) -} diff --git a/src/contract/consensus/src/lib.rs b/src/contract/consensus/src/lib.rs index deeef147d..93ef923f4 100644 --- a/src/contract/consensus/src/lib.rs +++ b/src/contract/consensus/src/lib.rs @@ -26,11 +26,8 @@ use darkfi_sdk::error::ContractError; pub enum ConsensusFunction { GenesisStakeV1 = 0x00, StakeV1 = 0x01, - ProposalBurnV1 = 0x02, - ProposalRewardV1 = 0x03, - ProposalMintV1 = 0x04, - UnstakeV1 = 0x05, - ProposalV1 = 0x06, + ProposalV1 = 0x02, + UnstakeV1 = 0x03, } impl TryFrom for ConsensusFunction { @@ -40,11 +37,8 @@ impl TryFrom for ConsensusFunction { match b { 0x00 => Ok(Self::GenesisStakeV1), 0x01 => Ok(Self::StakeV1), - 0x02 => Ok(Self::ProposalBurnV1), - 0x03 => Ok(Self::ProposalRewardV1), - 0x04 => Ok(Self::ProposalMintV1), - 0x05 => Ok(Self::UnstakeV1), - 0x06 => Ok(Self::ProposalV1), + 0x02 => Ok(Self::ProposalV1), + 0x03 => Ok(Self::UnstakeV1), _ => Err(ContractError::InvalidFunction), } } diff --git a/src/contract/consensus/tests/harness.rs b/src/contract/consensus/tests/harness.rs index d6d78c03c..d86108a48 100644 --- a/src/contract/consensus/tests/harness.rs +++ b/src/contract/consensus/tests/harness.rs @@ -47,7 +47,7 @@ use rand::rngs::OsRng; use darkfi_consensus_contract::{ client::{ genesis_stake_v1::ConsensusGenesisStakeCallBuilder, - proposal_v1_2::ConsensusProposalCallBuilder, stake_v1::ConsensusStakeCallBuilder, + proposal_v1::ConsensusProposalCallBuilder, stake_v1::ConsensusStakeCallBuilder, unstake_v1::ConsensusUnstakeCallBuilder, }, model::{ConsensusGenesisStakeParamsV1, ConsensusProposalParamsV1}, @@ -63,8 +63,7 @@ use darkfi_money_contract::{ Output, }, MoneyFunction, CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1, CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1, - CONSENSUS_CONTRACT_ZKAS_PROPOSAL_MINT_NS_V1, CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1, - CONSENSUS_CONTRACT_ZKAS_PROPOSAL_REWARD_NS_V1, MONEY_CONTRACT_ZKAS_BURN_NS_V1, + CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1, }; @@ -233,12 +232,8 @@ impl ConsensusTestHarness { &CONSENSUS_CONTRACT_ID, SMART_CONTRACT_ZKAS_DB_NAME, )?; - mkpk!(MONEY_CONTRACT_ZKAS_MINT_NS_V1); mkpk!(CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1); - mkpk!(MONEY_CONTRACT_ZKAS_BURN_NS_V1); mkpk!(CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1); - mkpk!(CONSENSUS_CONTRACT_ZKAS_PROPOSAL_REWARD_NS_V1); - mkpk!(CONSENSUS_CONTRACT_ZKAS_PROPOSAL_MINT_NS_V1); mkpk!(CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1); holders.insert(Holder::Alice, alice); diff --git a/src/contract/money/src/entrypoint/unstake_v1.rs b/src/contract/money/src/entrypoint/unstake_v1.rs index bef62a3c0..6f96f3295 100644 --- a/src/contract/money/src/entrypoint/unstake_v1.rs +++ b/src/contract/money/src/entrypoint/unstake_v1.rs @@ -142,8 +142,8 @@ pub(crate) fn money_unstake_process_instruction_v1( return Err(MoneyError::UnstakePreviousCallNotConsensusContract.into()) } - // Verify previous call corresponds to Consensus::UnstakeV1 (0x05) - if previous.data[0] != 0x05 { + // Verify previous call corresponds to Consensus::UnstakeV1 (0x03) + if previous.data[0] != 0x03 { msg!("[MoneyUnstakeV1] Error: Previous call function mismatch"); return Err(MoneyError::PreviousCallFunctionMissmatch.into()) } diff --git a/src/contract/money/src/lib.rs b/src/contract/money/src/lib.rs index 74e3798da..a80a2514c 100644 --- a/src/contract/money/src/lib.rs +++ b/src/contract/money/src/lib.rs @@ -104,9 +104,5 @@ pub const CONSENSUS_CONTRACT_COIN_MERKLE_TREE: &str = "consensus_coin_tree"; pub const CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1: &str = "ConsensusMint_V1"; /// zkas consensus burn circuit namespace pub const CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1: &str = "ConsensusBurn_V1"; -/// zkas proposal reward circuit namespace -pub const CONSENSUS_CONTRACT_ZKAS_PROPOSAL_REWARD_NS_V1: &str = "ProposalReward_V1"; -/// zkas proposal mint circuit namespace -pub const CONSENSUS_CONTRACT_ZKAS_PROPOSAL_MINT_NS_V1: &str = "ProposalMint_V1"; /// zkas proposal circuit namespace pub const CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1: &str = "ConsensusProposal_V1";