diff --git a/bin/darkfid/src/main.rs b/bin/darkfid/src/main.rs index 77eb42293..d20962d6e 100644 --- a/bin/darkfid/src/main.rs +++ b/bin/darkfid/src/main.rs @@ -30,9 +30,8 @@ use darkfi::{ consensus::{ constants::{ MAINNET_BOOTSTRAP_TIMESTAMP, MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP, - MAINNET_INITIAL_DISTRIBUTION, TESTNET_GENESIS_HASH_BYTES, - TESTNET_INITIAL_DISTRIBUTION, TESTNET_GENESIS_TIMESTAMP, - TESTNET_BOOTSTRAP_TIMESTAMP, + MAINNET_INITIAL_DISTRIBUTION, TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, + TESTNET_GENESIS_TIMESTAMP, TESTNET_INITIAL_DISTRIBUTION, }, proto::{ProtocolProposal, ProtocolSync, ProtocolSyncConsensus, ProtocolTx}, task::{block_sync_task, proposal_task}, @@ -49,7 +48,7 @@ use darkfi::{ }, server::{listen_and_serve, RequestHandler}, }, - util::{path::expand_path}, + util::path::expand_path, wallet::{walletdb::init_wallet, WalletPtr}, Error, Result, }; diff --git a/example/zk.rs b/example/zk.rs index eb7cd199e..9e8cd7188 100644 --- a/example/zk.rs +++ b/example/zk.rs @@ -28,15 +28,11 @@ use darkfi::{ Result, }; use darkfi_sdk::{ - crypto::{ - pedersen::pedersen_commitment_u64, poseidon_hash, MerkleNode, PublicKey, SecretKey, TokenId, - }, - incrementalmerkletree, - incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree}, + crypto::pedersen::pedersen_commitment_u64, pasta::{ arithmetic::CurveAffine, group::{ - ff::{Field, PrimeField}, + ff::Field, Curve, }, pallas, diff --git a/src/consensus/constants.rs b/src/consensus/constants.rs index 5bad74995..b02291d8d 100644 --- a/src/consensus/constants.rs +++ b/src/consensus/constants.rs @@ -124,6 +124,6 @@ pub const PI_SIGMA1_INDEX: usize = 12; pub const PI_SIGMA2_INDEX: usize = 13; pub const GENESIS_TOTAL_STAKE: u64 = 1; -pub const LEADER_HISTORY_LOG : &str = "/tmp/lead_history.log"; -pub const F_HISTORY_LOG : &str = "/tmp/f_history.log"; -pub const LOTTERY_HISTORY_LOG : &str = "/tmp/lottery_history.log"; +pub const LEADER_HISTORY_LOG: &str = "/tmp/lead_history.log"; +pub const F_HISTORY_LOG: &str = "/tmp/f_history.log"; +pub const LOTTERY_HISTORY_LOG: &str = "/tmp/lottery_history.log"; diff --git a/src/consensus/leadcoin.rs b/src/consensus/leadcoin.rs index d1b5a1ee9..91437e675 100644 --- a/src/consensus/leadcoin.rs +++ b/src/consensus/leadcoin.rs @@ -42,8 +42,10 @@ use crate::{ Result, }; -use std::io::{prelude::*, BufWriter}; -use std::fs::File; +use std::{ + fs::File, + io::{prelude::*, BufWriter}, +}; pub const MERKLE_DEPTH_LEADCOIN: usize = 32; pub const MERKLE_DEPTH: u8 = 32; @@ -130,10 +132,10 @@ impl LeadCoin { //info!("coin2_seed[{}]: {:?}", slot, coin2_seed); // Create commitment to coin2 //let coin2_commitment = Self::commitment( - //pk, - //pallas::Base::from(value + constants::REWARD), - //coin2_seed, - //coin2_blind, + //pk, + //pallas::Base::from(value + constants::REWARD), + //coin2_seed, + //coin2_blind, //); // Derive election seeds //let (y_mu, rho_mu) = Self::election_seeds_u64(eta, slot); @@ -187,12 +189,13 @@ impl LeadCoin { /// Create a vector of `pallas::Base` elements from the `LeadCoin` to be /// used as public inputs for the ZK proof. - pub fn public_inputs(&self, - sigma1: pallas::Base, - sigma2: pallas::Base, - current_eta: pallas::Base, - current_slot: pallas::Base, - derived_blind: pallas::Scalar, + pub fn public_inputs( + &self, + sigma1: pallas::Base, + sigma2: pallas::Base, + current_eta: pallas::Base, + current_slot: pallas::Base, + derived_blind: pallas::Scalar, ) -> Vec { // pk let pk = self.pk(); @@ -200,11 +203,8 @@ impl LeadCoin { let c1_cm_coord = self.coin1_commitment.to_affine().coordinates().unwrap(); let c2_cm_coord = self.derived_commitment(derived_blind).to_affine().coordinates().unwrap(); // lottery seed - let seed_msg = [pallas::Base::from(PREFIX_SEED), - self.coin1_sk_root.inner(), - self.nonce, - ZERO - ]; + let seed_msg = + [pallas::Base::from(PREFIX_SEED), self.coin1_sk_root.inner(), self.nonce, ZERO]; let seed = poseidon_hash(seed_msg); // y let (y_mu, rho_mu) = Self::election_seeds(current_eta, current_slot); @@ -282,16 +282,15 @@ impl LeadCoin { } */ - pub fn is_leader(&self, sigma1: pallas::Base, - sigma2: pallas::Base, - current_eta: pallas::Base, - current_slot: pallas::Base, + pub fn is_leader( + &self, + sigma1: pallas::Base, + sigma2: pallas::Base, + current_eta: pallas::Base, + current_slot: pallas::Base, ) -> bool { - let y_seed = [pallas::Base::from(PREFIX_SEED), - self.coin1_sk_root.inner(), - self.nonce, - ZERO - ]; + let y_seed = + [pallas::Base::from(PREFIX_SEED), self.coin1_sk_root.inner(), self.nonce, ZERO]; let y_seed_hash = poseidon_hash(y_seed); let (y_mu, _) = Self::election_seeds(current_eta, current_slot); let y_msg = [y_seed_hash, y_mu]; @@ -299,9 +298,9 @@ impl LeadCoin { let value = pallas::Base::from(self.value); - let target = sigma1 * value + sigma2 * value * value; + let target = sigma1 * value + sigma2 * value * value; - let y_t_str = format!("{:?},{:?}\n", y,target); + let y_t_str = format!("{:?},{:?}\n", y, target); let f = File::options().append(true).open(constants::LOTTERY_HISTORY_LOG).unwrap(); { @@ -447,7 +446,12 @@ impl LeadCoin { Witness::Base(Value::known(xferval)), ]; let circuit = ZkCircuit::new(witnesses, zkbin); - let proof = Proof::create(pk, &[circuit], &self.public_inputs(sigma1, sigma2, current_eta, current_slot, derived_blind), &mut OsRng)?; + let proof = Proof::create( + pk, + &[circuit], + &self.public_inputs(sigma1, sigma2, current_eta, current_slot, derived_blind), + &mut OsRng, + )?; let cm3_msg_in = [ pallas::Base::from(PREFIX_CM), change_pk, diff --git a/src/consensus/proto/protocol_proposal.rs b/src/consensus/proto/protocol_proposal.rs index 1135d3fe7..5867d096f 100644 --- a/src/consensus/proto/protocol_proposal.rs +++ b/src/consensus/proto/protocol_proposal.rs @@ -31,11 +31,9 @@ use crate::{ Result, }; -use darkfi_sdk::{ - pasta::{pallas}, -}; -use rand::rngs::OsRng; +use darkfi_sdk::pasta::pallas; use halo2_proofs::arithmetic::Field; +use rand::rngs::OsRng; pub struct ProtocolProposal { proposal_sub: MessageSubscription, diff --git a/src/consensus/state.rs b/src/consensus/state.rs index 22084aca0..ed0780ec5 100644 --- a/src/consensus/state.rs +++ b/src/consensus/state.rs @@ -36,8 +36,10 @@ use super::{ }; use crate::{blockchain::Blockchain, net, tx::Transaction, util::time::Timestamp, Error, Result}; -use std::io::{prelude::*, BufWriter}; -use std::fs::File; +use std::{ + fs::File, + io::{prelude::*, BufWriter}, +}; /// This struct represents the information required by the consensus algorithm pub struct ConsensusState { @@ -110,8 +112,7 @@ impl ConsensusState { slot_checkpoints: vec![], leaders_history: vec![0], f_history: vec![constants::FLOAT10_ZERO.clone()], - err_history: vec![constants::FLOAT10_ZERO.clone(), - constants::FLOAT10_ZERO.clone()], + err_history: vec![constants::FLOAT10_ZERO.clone(), constants::FLOAT10_ZERO.clone()], coins: vec![], coins_tree: BridgeTree::::new(constants::EPOCH_LENGTH * 100), nullifiers: vec![], @@ -261,20 +262,16 @@ impl ConsensusState { let neg_one = constants::FLOAT10_NEG_ONE.clone(); let two = constants::FLOAT10_TWO.clone(); - let field_p = Float10::try_from(constants::P).unwrap(); - - let x = one - f; let c = x.ln(); let neg_c = neg_one * c; - let sigma1_fbig = neg_c.clone() / total_sigma.clone() * field_p.clone(); + let sigma1_fbig = neg_c.clone() / total_sigma.clone() * field_p.clone(); println!("sigma1_fbig: {:}", sigma1_fbig); let sigma1 = fbig2base(sigma1_fbig); - let sigma2_fbig = (neg_c / total_sigma).powf(two.clone()) * (field_p / two); println!("sigma2_fbig: {:}", sigma2_fbig); let sigma2 = fbig2base(sigma2_fbig); @@ -282,12 +279,12 @@ impl ConsensusState { (sigma1, sigma2) } - /// Generate coins for provided sigmas. /// NOTE: The strategy here is having a single competing coin per slot. // TODO: DRK coin need to be burned, and consensus coin to be minted. - async fn create_coins(&mut self, - //eta: pallas::Base, + async fn create_coins( + &mut self, + //eta: pallas::Base, ) -> Result> { let slot = self.current_slot(); @@ -311,7 +308,6 @@ impl ConsensusState { // must sum to initial distribution total coins. //let stake = self.initial_distribution; let coin = LeadCoin::new( - 200, slot, epoch_secrets.secret_keys[0].inner(), @@ -399,7 +395,7 @@ impl ConsensusState { self.leaders_history.push(count); info!("extend_leaders_history(): Current leaders history: {:?}", self.leaders_history); - let mut count_str : String = count.to_string(); + let mut count_str: String = count.to_string(); count_str.push_str(","); let f = File::options().append(true).open(constants::LEADER_HISTORY_LOG).unwrap(); { @@ -408,35 +404,31 @@ impl ConsensusState { } Float10::try_from(count as i64).unwrap() - } - fn f_err(&mut self) -> Float10 { let len = self.leaders_history.len(); - let feedback = Float10::try_from(self.leaders_history[len-1] as i64).unwrap(); + let feedback = Float10::try_from(self.leaders_history[len - 1] as i64).unwrap(); let target = constants::FLOAT10_ONE.clone(); target - feedback } - fn discrete_pid(&mut self) -> Float10 { - let k1 = constants::KP.clone() + - constants::KI.clone() + - constants::KD.clone(); - let k2 = constants::FLOAT10_NEG_ONE.clone() * constants::KP.clone() + constants::FLOAT10_NEG_TWO.clone() * constants::KD.clone(); + let k1 = constants::KP.clone() + constants::KI.clone() + constants::KD.clone(); + let k2 = constants::FLOAT10_NEG_ONE.clone() * constants::KP.clone() + + constants::FLOAT10_NEG_TWO.clone() * constants::KD.clone(); let k3 = constants::KD.clone(); let f_len = self.f_history.len(); let err = self.f_err(); let err_len = self.err_history.len(); - let ret = self.f_history[f_len-1].clone() + + let ret = self.f_history[f_len - 1].clone() + k1.clone() * err.clone() + - k2.clone() * self.err_history[err_len-1].clone() + - k3.clone() * self.err_history[err_len-2].clone(); - info!("pid::f-1: {:}", self.f_history[f_len-1].clone()); + k2.clone() * self.err_history[err_len - 1].clone() + + k3.clone() * self.err_history[err_len - 2].clone(); + info!("pid::f-1: {:}", self.f_history[f_len - 1].clone()); info!("pid::err: {:}", err); - info!("pid::err-1: {}", self.err_history[err_len-1].clone()); - info!("pid::err-2: {}", self.err_history[err_len-2].clone()); + info!("pid::err-1: {}", self.err_history[err_len - 1].clone()); + info!("pid::err-2: {}", self.err_history[err_len - 2].clone()); info!("pid::k1: {}", k1.clone()); info!("pid::k2: {}", k2.clone()); info!("pid::k3: {}", k3.clone()); @@ -493,15 +485,16 @@ impl ConsensusState { let mut highest_stake_idx = 0; let total_stake = self.total_stake(); for (winning_idx, coin) in competing_coins.iter().enumerate() { - info!("is_slot_leader: coin stake: {:?}", coin.value); info!("is_slot_leader: total stake: {}", total_stake); info!("is_slot_leader: relative stake: {}", (coin.value as f64) / total_stake as f64); - let first_winning = coin.is_leader(sigma1, - sigma2, - self.get_eta(), - pallas::Base::from(self.current_slot())); + let first_winning = coin.is_leader( + sigma1, + sigma2, + self.get_eta(), + pallas::Base::from(self.current_slot()), + ); if first_winning && !won { highest_stake_idx = winning_idx; @@ -942,36 +935,28 @@ impl From for Fork { #[cfg(test)] mod tests { - use darkfi_sdk::{ - pasta::{group::ff::PrimeField, pallas}, - }; - use log::info; - - use crate::consensus::{ - constants, - state::ConsensusState, - utils::fbig2base, - Float10, - }; - - use crate::{ Error, Result}; - use dashu::base::Abs; - - use std::io::{prelude::*, BufWriter}; - use std::fs::File; + use crate::consensus::{state::ConsensusState, utils::fbig2base, Float10}; #[test] fn calc_sigmas_test() { - let giga_epsilon = Float10::try_from("10000000000000000000000000000000000000000000000000000000000").unwrap(); + let giga_epsilon = + Float10::try_from("10000000000000000000000000000000000000000000000000000000000") + .unwrap(); let giga_epsilon_base = fbig2base(giga_epsilon); let f = Float10::try_from("0.5").unwrap(); let total_stake = Float10::try_from("1000").unwrap(); let (sigma1, sigma2) = ConsensusState::calc_sigmas(f, total_stake); - let sigma1_rhs = Float10::try_from("20065240046497827749443820209808913616958821867408735207193448041041362944").unwrap(); + let sigma1_rhs = Float10::try_from( + "20065240046497827749443820209808913616958821867408735207193448041041362944", + ) + .unwrap(); let sigma1_rhs_base = fbig2base(sigma1_rhs); - let sigma2_rhs = Float10::try_from("6954082282744237239883318512759812991231744634473746668074299461468160").unwrap(); + let sigma2_rhs = Float10::try_from( + "6954082282744237239883318512759812991231744634473746668074299461468160", + ) + .unwrap(); let sigma2_rhs_base = fbig2base(sigma2_rhs); - let sigma1_delta = if sigma1_rhs_base>sigma1 { + let sigma1_delta = if sigma1_rhs_base > sigma1 { sigma1_rhs_base - sigma1 } else { sigma1 - sigma1_rhs_base diff --git a/src/consensus/task/proposal.rs b/src/consensus/task/proposal.rs index 46cc026ad..eac655046 100644 --- a/src/consensus/task/proposal.rs +++ b/src/consensus/task/proposal.rs @@ -28,11 +28,9 @@ use crate::{ util::{async_util::sleep, time::Timestamp}, }; -use darkfi_sdk::{ - pasta::{pallas}, -}; -use rand::rngs::OsRng; +use darkfi_sdk::pasta::pallas; use halo2_proofs::arithmetic::Field; +use rand::rngs::OsRng; /// async task used for participating in the consensus protocol pub async fn proposal_task( @@ -186,9 +184,10 @@ async fn consensus_loop( /// - Generate slot sigmas and checkpoint /// - Check if slot leader to generate and broadcast proposal /// Returns flag in case node needs to resync. -async fn propose_period(consensus_p2p: P2pPtr, - state: ValidatorStatePtr, - derived_blind: pallas::Scalar, +async fn propose_period( + consensus_p2p: P2pPtr, + state: ValidatorStatePtr, + derived_blind: pallas::Scalar, ) -> bool { // Node sleeps until next slot let seconds_next_slot = state.read().await.consensus.next_n_slot_start(1).as_secs(); @@ -219,12 +218,13 @@ async fn propose_period(consensus_p2p: P2pPtr, let (won, fork_index, coin_index) = state.write().await.consensus.is_slot_leader(sigma1, sigma2); let result = if won { - state.write().await.propose(processing_slot, - fork_index, - coin_index, - sigma1, - sigma2, - derived_blind + state.write().await.propose( + processing_slot, + fork_index, + coin_index, + sigma1, + sigma2, + derived_blind, ) } else { Ok(None) @@ -258,7 +258,12 @@ async fn propose_period(consensus_p2p: P2pPtr, info!("consensus: Node is the slot leader: Proposed block: {}", proposal); debug!("consensus: Full proposal: {:?}", proposal); - match state.write().await.receive_proposal(&proposal, Some((coin_index, coin)), derived_blind).await { + match state + .write() + .await + .receive_proposal(&proposal, Some((coin_index, coin)), derived_blind) + .await + { Ok(_) => { // Here we don't have to check to broadcast, because the flag // will always be true, since the node is able to produce proposals diff --git a/src/consensus/utils.rs b/src/consensus/utils.rs index 6c4c0c7bf..abf01886a 100644 --- a/src/consensus/utils.rs +++ b/src/consensus/utils.rs @@ -16,11 +16,9 @@ * along with this program. If not, see . */ -use darkfi_sdk::pasta::pallas; -use dashu::integer::{IBig, Sign}; +use darkfi_sdk::pasta::{group::ff::PrimeField, pallas}; +use dashu::integer::{IBig, Sign, UBig}; use log::debug; -use dashu::integer::UBig; -use darkfi_sdk::pasta::group::ff::PrimeField; use super::Float10; @@ -71,9 +69,11 @@ pub fn base2ibig(base: pallas::Base) -> IBig { mod tests { use dashu::integer::IBig; - use darkfi_sdk::pasta::{pallas, group::ff::PrimeField}; - use crate::consensus::{constants::RADIX_BITS, types::Float10, utils::{fbig2ibig, fbig2base, base2ibig}}; - + use crate::consensus::{ + types::Float10, + utils::{base2ibig, fbig2base, fbig2ibig}, + }; + use darkfi_sdk::pasta::pallas; #[test] fn dashu_fbig2ibig() { @@ -86,7 +86,10 @@ mod tests { #[test] fn dashu_test_base2ibig() { // - let fbig: Float10 = Float10::from_str_native("289480223093290488558927462521719769633630564819415607159546767643499676303").unwrap().with_precision(RADIX_BITS).value(); + let fbig: Float10 = Float10::try_from( + "289480223093290488558927462521719769633630564819415607159546767643499676303", + ) + .unwrap(); let ibig = fbig2ibig(fbig.clone()); let res_base: pallas::Base = fbig2base(fbig.clone()); let res_ibig: IBig = base2ibig(res_base); @@ -96,7 +99,10 @@ mod tests { #[test] fn dashu_test2_base2ibig() { //assert that field wrapping for negative values won't hold during conversions. - let fbig: Float10 = Float10::from_str_native("-20065240046497827215558476051577517633529246907153511707181011345840062564.87").unwrap().with_precision(RADIX_BITS).value(); + let fbig: Float10 = Float10::try_from( + "-20065240046497827215558476051577517633529246907153511707181011345840062564.87", + ) + .unwrap(); let ibig = fbig2ibig(fbig.clone()); let res_base: pallas::Base = fbig2base(fbig.clone()); let res_ibig: IBig = base2ibig(res_base); diff --git a/src/consensus/validator.rs b/src/consensus/validator.rs index 592aec3f1..a0c566ac2 100644 --- a/src/consensus/validator.rs +++ b/src/consensus/validator.rs @@ -264,7 +264,7 @@ impl ValidatorState { coin_index: usize, sigma1: pallas::Base, sigma2: pallas::Base, - derived_blind: pallas::Scalar + derived_blind: pallas::Scalar, ) -> Result> { let eta = self.consensus.get_eta(); // Check if node can produce proposals @@ -292,12 +292,13 @@ impl ValidatorState { }; // Generating leader proof - let (proof, public_inputs) = coin.create_lead_proof(sigma1, - sigma2, - eta.clone(), - pallas::Base::from(self.consensus.current_slot()), - self.lead_proving_key.as_ref().unwrap(), - derived_blind, + let (proof, public_inputs) = coin.create_lead_proof( + sigma1, + sigma2, + eta.clone(), + pallas::Base::from(self.consensus.current_slot()), + self.lead_proving_key.as_ref().unwrap(), + derived_blind, ); // Signing using coin @@ -475,8 +476,8 @@ impl ValidatorState { info!(target: "consensus::validator", "receive_proposal(): Leader proof verified successfully!"); // Validate proposal public value against coin creation slot checkpoint - let (mu_y, mu_rho) = LeadCoin::election_seeds_u64(self.consensus.get_eta(), - self.consensus.current_slot()); + let (mu_y, mu_rho) = + LeadCoin::election_seeds_u64(self.consensus.get_eta(), self.consensus.current_slot()); // y let prop_mu_y = lf.public_inputs[constants::PI_MU_Y_INDEX]; @@ -501,7 +502,6 @@ impl ValidatorState { return Err(Error::ProposalPublicValuesMismatched) } - // Validate proposal coin sigmas against current slot checkpoint let checkpoint = self.consensus.get_slot_checkpoint(current)?; // sigma1 @@ -567,7 +567,8 @@ impl ValidatorState { // If proposal came fromself, we derive new coin if let Some((idx, c)) = coin { - state_checkpoint.coins[idx] = c.derive_coin(&mut state_checkpoint.coins_tree, derived_blind); + state_checkpoint.coins[idx] = + c.derive_coin(&mut state_checkpoint.coins_tree, derived_blind); } // Store proposal coins nullifiers state_checkpoint.nullifiers.push(prop_sn); @@ -647,12 +648,11 @@ impl ValidatorState { return Ok((vec![], vec![])) } _ => info!("chain_finalization(): Chain {} can be finalized!", fork_index), - } - if max_length==0 { + if max_length == 0 { return Ok((vec![], vec![])) } - if max_length==0 { + if max_length == 0 { return Ok((vec![], vec![])) } diff --git a/src/contract/money/src/client.rs b/src/contract/money/src/client.rs index f8b2d1587..b80c4d932 100644 --- a/src/contract/money/src/client.rs +++ b/src/contract/money/src/client.rs @@ -1061,7 +1061,6 @@ pub fn build_stake_tx( burn_zkbin: &ZkBinary, burn_pk: &ProvingKey, slot_index: u64, - eta: pallas::Base, ) -> Result<(MoneyStakeParams, Vec, Vec, Vec, Vec)> { // convert owncoins to leadcoins. // TODO: verify this token blind usage @@ -1117,7 +1116,6 @@ pub fn build_stake_tx( let sk_root = sk_tree.root(0).unwrap(); let sk_merkle_path = sk_tree.authentication_path(sk_pos, &sk_root).unwrap(); let leadcoin = LeadCoin::new( - eta, // randomness from last finalized block. coin.note.value, slot_index, // tau coin.secret.inner(), // coin secret key diff --git a/src/contract/money/tests/verification_bench.rs b/src/contract/money/tests/verification_bench.rs index 61cfe8b65..2184d6340 100644 --- a/src/contract/money/tests/verification_bench.rs +++ b/src/contract/money/tests/verification_bench.rs @@ -100,6 +100,9 @@ async fn alice2alice_random_amounts() -> Result<()> { &th.alice_kp.public, amount, token_id, + pallas::Base::zero(), + pallas::Base::zero(), + pallas::Base::random(&mut OsRng), &owncoins, &th.alice_merkle_tree, &th.mint_zkbin, @@ -239,6 +242,9 @@ async fn alice2alice_random_amounts_multiplecoins() -> Result<()> { &th.alice_kp.public, amount, token_id, + pallas::Base::zero(), + pallas::Base::zero(), + pallas::Base::random(&mut OsRng), &coins, &th.alice_merkle_tree, &th.mint_zkbin,