contract: Use native constants instead of wrapped ones for ZERO.

This commit is contained in:
parazyd
2023-06-07 14:25:57 +02:00
parent e77f801a1f
commit 95a2da019b
11 changed files with 47 additions and 44 deletions

View File

@@ -26,7 +26,7 @@ use darkfi::{
};
use darkfi_money_contract::{
client::{ConsensusNote, ConsensusOwnCoin},
model::{Coin, ConsensusInput, ConsensusOutput, PALLAS_ZERO},
model::{Coin, ConsensusInput, ConsensusOutput},
};
use darkfi_sdk::{
crypto::{
@@ -271,7 +271,7 @@ pub fn create_proposal_proof(
new_pub_x,
new_pub_y,
new_value_pallas,
PALLAS_ZERO,
pallas::Base::ZERO,
new_serial,
output.coin_blind,
]));

View File

@@ -17,10 +17,8 @@
*/
use darkfi_money_contract::{
error::MoneyError,
model::{ConsensusStakeUpdateV1, PALLAS_ZERO},
CONSENSUS_CONTRACT_COINS_TREE, CONSENSUS_CONTRACT_UNSTAKED_COINS_TREE,
CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1,
error::MoneyError, model::ConsensusStakeUpdateV1, CONSENSUS_CONTRACT_COINS_TREE,
CONSENSUS_CONTRACT_UNSTAKED_COINS_TREE, CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1,
};
use darkfi_sdk::{
crypto::{pasta_prelude::*, pedersen_commitment_u64, ContractId, DARK_TOKEN_ID},
@@ -36,6 +34,10 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
use crate::{model::ConsensusGenesisStakeParamsV1, ConsensusFunction};
/// `get_metadata` function for `Consensus::GenesisStakeV1`
///
/// Here we gather the signature pubkey from the clear input in order
/// to verify the transaction, and we extract the necessary public inputs
/// that go into the `ConsensusMint_V1` proof verification.
pub(crate) fn consensus_genesis_stake_get_metadata_v1(
_cid: ContractId,
call_idx: u32,
@@ -50,15 +52,14 @@ pub(crate) fn consensus_genesis_stake_get_metadata_v1(
let signature_pubkeys = vec![params.input.signature_public];
// Genesis stake only happens on epoch 0
let epoch = PALLAS_ZERO;
let epoch = pallas::Base::ZERO;
// Grab the pedersen commitment from the anonymous output
let output = &params.output;
let value_coords = output.value_commit.to_affine().coordinates().unwrap();
let value_coords = params.output.value_commit.to_affine().coordinates().unwrap();
zk_public_inputs.push((
CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1.to_string(),
vec![epoch, output.coin.inner(), *value_coords.x(), *value_coords.y()],
vec![epoch, params.output.coin.inner(), *value_coords.x(), *value_coords.y()],
));
// Serialize everything gathered and return it
@@ -78,7 +79,7 @@ pub(crate) fn consensus_genesis_stake_process_instruction_v1(
let self_ = &calls[call_idx as usize];
let params: ConsensusGenesisStakeParamsV1 = deserialize(&self_.data[1..])?;
// Verify this contract call is verified against on genesis slot(0).
// Verify this contract call is verified on the genesis slot (0).
let verifying_slot = get_verifying_slot();
if verifying_slot != 0 {
msg!("[GenesisStakeV1] Error: Call is executed for slot {}, not genesis", verifying_slot);
@@ -99,19 +100,18 @@ pub(crate) fn consensus_genesis_stake_process_instruction_v1(
// Check that the coin from the output hasn't existed before.
let coin = serialize(&params.output.coin);
if db_contains_key(coins_db, &coin)? {
msg!("[GenesisStakeV1] Error: Duplicate coin in output");
msg!("[GenesisStakeV1] Error: Output coin was already seen in the set of staked coins");
return Err(MoneyError::DuplicateCoin.into())
}
// Check that the coin from the output hasn't existed before in unstake set.
if db_contains_key(unstaked_coins_db, &coin)? {
msg!("[GenesisStakeV1] Error: Duplicate coin in output");
msg!("[GenesisStakeV1] Error: Output coin was already seen in the set of unstaked coins");
return Err(MoneyError::DuplicateCoin.into())
}
// Verify that the value commitment match. In here we just
// confirm that the clear input and the anon output have the same
// commitment.
// Verify that the value commitments match. In here we just confirm
// that the clear input and the anon output have the same commitment.
if pedersen_commitment_u64(params.input.value, params.input.value_blind) !=
params.output.value_commit
{

View File

@@ -18,7 +18,7 @@
use darkfi_money_contract::{
error::MoneyError,
model::{ConsensusStakeParamsV1, ConsensusStakeUpdateV1, MoneyStakeParamsV1, PALLAS_ZERO},
model::{ConsensusStakeParamsV1, ConsensusStakeUpdateV1, MoneyStakeParamsV1},
CONSENSUS_CONTRACT_COINS_TREE, CONSENSUS_CONTRACT_COIN_MERKLE_TREE,
CONSENSUS_CONTRACT_COIN_ROOTS_TREE, CONSENSUS_CONTRACT_INFO_TREE,
CONSENSUS_CONTRACT_UNSTAKED_COINS_TREE, CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1,
@@ -142,7 +142,7 @@ pub(crate) fn consensus_stake_process_instruction_v1(
}
// If spend hook is set, check its correctness
if previous_input.spend_hook != PALLAS_ZERO &&
if previous_input.spend_hook != pallas::Base::ZERO &&
previous_input.spend_hook != CONSENSUS_CONTRACT_ID.inner()
{
msg!("[ConsensusStakeV1] Error: Invoking contract call does not match spend hook in input");

View File

@@ -25,12 +25,14 @@ use darkfi_serial::{SerialDecodable, SerialEncodable};
/// Parameters for `Consensus::GenesisStake`
#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
// ANCHOR: ConsensusGenesisStakeParams
pub struct ConsensusGenesisStakeParamsV1 {
/// Clear input
pub input: ClearInput,
/// Anonymous output
pub output: ConsensusOutput,
}
// ANCHOR_END: ConsensusGenesisStakeParams
/// Parameters for `Consensus::Proposal`
#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
@@ -73,16 +75,19 @@ pub struct ConsensusUnstakeRequestParamsV1 {
pub output: Output,
}
/// Consensus parameters configuration.
/// Note: Always verify `pallas::Base` are correct, in case of changes,
/// using pallas_constants tool.
// ==================================
// Consensus parameters configuration
// Note: Always verify `pallas::Base` are correct, in case of changes,
// using pallas_constants tool.
// ==================================
/// Number of slots in one epoch
pub const EPOCH_LENGTH: u64 = 10;
/// Slot time in seconds
pub const SLOT_TIME: u64 = 90;
/// Grace period days target
pub const GRACE_PERIOD_DAYS: u64 = 2;
/// Configured reward
/// Configured block 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]);
@@ -118,7 +123,8 @@ pub struct SlotCheckpoint {
/// Auxiliary function to calculate the grace(locked) period, denominated
/// in epochs.
pub fn calculate_grace_period() -> u64 {
#[inline]
pub const fn calculate_grace_period() -> u64 {
// 86400 seconds in a day
(86400 * GRACE_PERIOD_DAYS) / (SLOT_TIME * EPOCH_LENGTH)
}

View File

@@ -32,7 +32,7 @@ use darkfi_sdk::{
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use crate::model::{Coin, PALLAS_ZERO, SCALAR_ZERO};
use crate::model::Coin;
/// `Money::TransferV1` API
pub mod transfer_v1;
@@ -159,11 +159,11 @@ impl From<ConsensusNote> for MoneyNote {
serial: consensus_note.serial,
value: consensus_note.value,
token_id: *DARK_TOKEN_ID,
spend_hook: PALLAS_ZERO,
user_data: PALLAS_ZERO,
spend_hook: pallas::Base::ZERO,
user_data: pallas::Base::ZERO,
coin_blind: consensus_note.coin_blind,
value_blind: consensus_note.value_blind,
token_blind: SCALAR_ZERO,
token_blind: pallas::Scalar::ZERO,
memo: vec![],
}
}

View File

@@ -36,7 +36,7 @@ use rand::rngs::OsRng;
use crate::{
client::{ConsensusOwnCoin, MoneyNote},
model::{Coin, ConsensusInput, MoneyUnstakeParamsV1, Output, PALLAS_ZERO, SCALAR_ZERO},
model::{Coin, ConsensusInput, MoneyUnstakeParamsV1, Output},
};
pub struct MoneyUnstakeCallDebris {
@@ -105,9 +105,9 @@ impl MoneyUnstakeCallBuilder {
debug!("Finished building output");
let serial = pallas::Base::random(&mut OsRng);
let spend_hook = PALLAS_ZERO;
let user_data_enc = PALLAS_ZERO;
let token_blind = SCALAR_ZERO;
let spend_hook = pallas::Base::ZERO;
let user_data_enc = pallas::Base::ZERO;
let token_blind = pallas::Scalar::ZERO;
let coin_blind = pallas::Base::random(&mut OsRng);
info!("Creating unstake mint proof for output");

View File

@@ -31,7 +31,7 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
use crate::{
error::MoneyError,
model::{ConsensusStakeParamsV1, MoneyStakeParamsV1, MoneyStakeUpdateV1, PALLAS_ZERO},
model::{ConsensusStakeParamsV1, MoneyStakeParamsV1, MoneyStakeUpdateV1},
MoneyFunction, MONEY_CONTRACT_COIN_ROOTS_TREE, MONEY_CONTRACT_NULLIFIERS_TREE,
MONEY_CONTRACT_ZKAS_BURN_NS_V1,
};
@@ -137,7 +137,7 @@ pub(crate) fn money_stake_process_instruction_v1(
}
// If spend hook is set, check its correctness
if input.spend_hook != PALLAS_ZERO && next.contract_id.inner() != input.spend_hook {
if input.spend_hook != pallas::Base::ZERO && next.contract_id.inner() != input.spend_hook {
msg!("[MoneyStakeV1] Error: Invoking contract call does not match spend hook in input");
return Err(MoneyError::SpendHookMismatch.into())
}

View File

@@ -27,7 +27,7 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
use super::transfer_v1::{money_transfer_get_metadata_v1, money_transfer_process_update_v1};
use crate::{
error::MoneyError,
model::{MoneyTransferParamsV1, MoneyTransferUpdateV1, PALLAS_ZERO},
model::{MoneyTransferParamsV1, MoneyTransferUpdateV1},
MoneyFunction, MONEY_CONTRACT_COINS_TREE, MONEY_CONTRACT_COIN_ROOTS_TREE,
MONEY_CONTRACT_NULLIFIERS_TREE,
};
@@ -110,7 +110,7 @@ pub(crate) fn money_otcswap_process_instruction_v1(
// For now, make sure that the inputs' spend hooks are zero.
// This should however be allowed to some extent, e.g. if we
// want a DAO to be able to do an atomic swap.
if input.spend_hook != PALLAS_ZERO {
if input.spend_hook != pallas::Base::ZERO {
msg!("[OtcSwapV1] Error: Unable to swap coins with spend_hook != 0 (input {})", i);
return Err(MoneyError::SpendHookNonZero.into())
}

View File

@@ -31,7 +31,7 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
use crate::{
error::MoneyError,
model::{MoneyTransferParamsV1, MoneyTransferUpdateV1, PALLAS_ZERO},
model::{MoneyTransferParamsV1, MoneyTransferUpdateV1},
MoneyFunction, MONEY_CONTRACT_COINS_TREE, MONEY_CONTRACT_COIN_MERKLE_TREE,
MONEY_CONTRACT_COIN_ROOTS_TREE, MONEY_CONTRACT_FAUCET_PUBKEYS, MONEY_CONTRACT_INFO_TREE,
MONEY_CONTRACT_NULLIFIERS_TREE, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
@@ -193,7 +193,7 @@ pub(crate) fn money_transfer_process_instruction_v1(
}
// If spend hook is set, check its correctness
if input.spend_hook != PALLAS_ZERO {
if input.spend_hook != pallas::Base::ZERO {
let next_call_idx = call_idx + 1;
if next_call_idx >= calls.len() as u32 {
msg!("[TransferV1] Error: next_call_idx out of bounds (input {})", i);

View File

@@ -31,7 +31,7 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
use crate::{
error::MoneyError,
model::{ConsensusUnstakeParamsV1, MoneyUnstakeParamsV1, MoneyUnstakeUpdateV1, PALLAS_ZERO},
model::{ConsensusUnstakeParamsV1, MoneyUnstakeParamsV1, MoneyUnstakeUpdateV1},
MoneyFunction, CONSENSUS_CONTRACT_COIN_ROOTS_TREE, CONSENSUS_CONTRACT_NULLIFIERS_TREE,
MONEY_CONTRACT_COINS_TREE, MONEY_CONTRACT_COIN_MERKLE_TREE, MONEY_CONTRACT_COIN_ROOTS_TREE,
MONEY_CONTRACT_INFO_TREE, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
@@ -157,7 +157,7 @@ pub(crate) fn money_unstake_process_instruction_v1(
}
// If next spend hook is set, check its correctness
if params.spend_hook != PALLAS_ZERO {
if params.spend_hook != pallas::Base::ZERO {
let next_call_idx = call_idx + 1;
if next_call_idx >= calls.len() as u32 {
msg!("[MoneyUnstakeV1] Error: next_call_idx out of bounds");

View File

@@ -248,10 +248,12 @@ pub struct ConsensusStakeParamsV1 {
/// State update for `Consensus::Stake`
#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
// ANCHOR: ConsensusStakeUpdate
pub struct ConsensusStakeUpdateV1 {
/// The newly minted coin
pub coin: Coin,
}
// ANCHOR_END: ConsensusStakeUpdate
/// Parameters for `Consensus::Unstake`
#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
@@ -266,8 +268,3 @@ pub struct ConsensusUnstakeUpdateV1 {
/// Revealed nullifier
pub nullifier: Nullifier,
}
// `pallas::Base` used as prefix/suffix in poseidon hash
pub const PALLAS_ZERO: pallas::Base = pallas::Base::zero();
// `pallas::Scalar` used as prefix/suffix in poseidon hash
pub const SCALAR_ZERO: pallas::Scalar = pallas::Scalar::zero();