Browse Source

bin/dao: Show the token id as a string, airdrop() pass PublicKey and Rename xDRK and gDRK to DRK and GOV

Dastan-glitch 3 năm trước cách đây
mục cha
commit
f5490477ca

+ 2 - 0
Cargo.lock

@@ -1126,6 +1126,7 @@ dependencies = [
  "futures",
  "log",
  "num_cpus",
+ "prettytable-rs",
  "serde_json",
  "simplelog",
  "smol",
@@ -1145,6 +1146,7 @@ dependencies = [
  "darkfi",
  "easy-parallel",
  "futures",
+ "fxhash",
  "group",
  "halo2_gadgets",
  "halo2_proofs",

+ 1 - 0
bin/dao/dao-cli/Cargo.toml

@@ -22,6 +22,7 @@ log = "0.4.17"
 num_cpus = "1.13.1"
 simplelog = "0.12.0"
 url = "2.2.2"
+prettytable-rs = "0.9.0"
 
 # Encoding and parsing
 serde_json = "1.0.85"

+ 12 - 2
bin/dao/dao-cli/run_demo.sh

@@ -6,8 +6,18 @@ addr3=${addr2::-1}
 echo $addr3
 
 cargo run mint 1000000 $addr3
-cargo run keygen alice 
-cargo run keygen bob
+
+alice=$(cargo run keygen alice)
+alice=$(cargo run keygen alice | cut -d " " -f 4)
+alice2=$(echo $alice | cut -c 2-)
+alice3=${alice2::-1}
+echo $alice3
+
+bob=$(cargo run keygen bob)
+bob=$(cargo run keygen bob | cut -d " " -f 4)
+bob2=$(echo $bob | cut -c 2-)
+bob3=${bob2::-1}
+echo $bob3
 
 charlie=$(cargo run keygen charlie)
 charlie=$(cargo run keygen charlie | cut -d " " -f 4)

+ 55 - 4
bin/dao/dao-cli/src/main.rs

@@ -1,4 +1,7 @@
+use std::process::exit;
+
 use clap::{IntoApp, Parser, Subcommand};
+use prettytable::{format, row, Table};
 use url::Url;
 
 use darkfi::{rpc::client::RpcClient, Result};
@@ -134,8 +137,32 @@ async fn start(options: CliDao) -> Result<()> {
             return Ok(())
         }
         Some(CliDaoSubCommands::DaoBalance {}) => {
-            let reply = client.dao_balance().await?;
-            println!("DAO balance: {}", &reply.to_string());
+            let rep = client.dao_balance().await?;
+
+            if !rep.is_object() {
+                eprintln!("Invalid balance data received from darkfid RPC endpoint.");
+                exit(1);
+            }
+
+            let mut table = Table::new();
+            table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
+            table.set_titles(row!["Token", "Balance"]);
+
+            for i in rep.as_object().unwrap().keys() {
+                if let Some(balance) = rep[i].as_u64() {
+                    table.add_row(row![i, balance]);
+                    continue
+                }
+
+                eprintln!("Found invalid balance data for key \"{}\"", i);
+            }
+
+            if table.is_empty() {
+                println!("No balances.");
+            } else {
+                println!("{}", table);
+            }
+            // println!("DAO balance: {}", &reply.to_string());
             return Ok(())
         }
         Some(CliDaoSubCommands::DaoBulla {}) => {
@@ -144,8 +171,32 @@ async fn start(options: CliDao) -> Result<()> {
             return Ok(())
         }
         Some(CliDaoSubCommands::UserBalance { nym }) => {
-            let reply = client.user_balance(nym).await?;
-            println!("User balance: {}", &reply.to_string());
+            let rep = client.user_balance(nym).await?;
+
+            if !rep.is_object() {
+                eprintln!("Invalid balance data received from darkfid RPC endpoint.");
+                exit(1);
+            }
+
+            let mut table = Table::new();
+            table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
+            table.set_titles(row!["Token", "Balance"]);
+
+            for i in rep.as_object().unwrap().keys() {
+                if let Some(balance) = rep[i].as_u64() {
+                    table.add_row(row![i, balance]);
+                    continue
+                }
+
+                eprintln!("Found invalid balance data for key \"{}\"", i);
+            }
+
+            if table.is_empty() {
+                println!("No balances.");
+            } else {
+                println!("{}", table);
+            }
+            // println!("User balance: {}", &reply.to_string());
             return Ok(())
         }
         Some(CliDaoSubCommands::Propose { sender, recipient, amount }) => {

+ 1 - 0
bin/dao/daod/Cargo.toml

@@ -35,6 +35,7 @@ group = "0.12.0"
 # Encoding and parsing
 serde_json = "1.0.85"
 bs58 = "0.4.0"
+fxhash = "0.2.1"
 
 # Utilities
 lazy_static = "1.4.0"

+ 26 - 16
bin/dao/daod/src/main.rs

@@ -1,5 +1,7 @@
 use std::{any::TypeId, collections::HashMap, sync::Arc, time::Instant};
 
+use fxhash::FxHashMap;
+use group::ff::PrimeField;
 use incrementalmerkletree::{Position, Tree};
 use log::debug;
 use pasta_curves::{
@@ -37,7 +39,7 @@ use crate::{
     },
     rpc::JsonRpcInterface,
     util::{
-        sign, FuncCall, HashableBase, StateRegistry, Transaction, ZkContractTable, GDRK_ID, XDRK_ID,
+        sign, FuncCall, HashableBase, StateRegistry, Transaction, ZkContractTable, DRK_ID, GOV_ID,
     },
 };
 
@@ -120,28 +122,28 @@ use crate::{
 ////
 //// 3. Rename xDRK and gDRK to DRK and GOV (xDRK = DRK, gDRK = GOV)
 ////
-//// 5. Change MoneyWallets to be a HashMap<PublicKey, MoneyWallet>
+//// 4. Change MoneyWallets to be a HashMap<PublicKey, MoneyWallet>
 ////
-//// 6. vote() should pass a ProposalBulla
+//// 5. vote() should pass a ProposalBulla
 ////
 //// Less priority:
 ////
-//// 5. Better document CLI/ CLI help.
+//// 6. Better document CLI/ CLI help.
 ////
-//// 4. Token id is hardcoded rn. Change this so users can specify token_id
+//// 7. Token id is hardcoded rn. Change this so users can specify token_id
 ////    as either xdrk or gdrk. In dao-cli we run a match statement to link to
 ////    the corresponding static values XDRK_ID and GDRK_ID. Note: xdrk is used
 ////    only for the DAO treasury. gdrk is the governance token used to operate
 ////    the DAO.
 ////
-//// 5. Implement money transfer between MoneyWallets so users can send tokens to
+//// 8. Implement money transfer between MoneyWallets so users can send tokens to
 ////    eachother.
 ////
-//// 6. Make CLI usage more interactive. Example: when I cast a vote, output:
+//// 9. Make CLI usage more interactive. Example: when I cast a vote, output:
 ////   "You voted {} with value {}." where value is the number of gDRK in a users
 ////    wallet (and the same for making a proposal etc).
 ////
-//// 7. Currently, DaoWallet stores DaoParams, DaoBulla's and Proposal's in a
+//// 10. Currently, DaoWallet stores DaoParams, DaoBulla's and Proposal's in a
 ////    Vector. We retrieve values through indexing, meaning that we
 ////    cannot currently support multiple DAOs and multiple proposals.
 ////
@@ -151,7 +153,7 @@ use crate::{
 ////    ProposalBulla and we lookup the corresponding data. struct Dao should
 ////    be owned by DaoWallet.
 ////
-//// 8. Error handling :)
+//// 11. Error handling :)
 ////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -309,7 +311,7 @@ impl Client {
 
         let tx = self
             .cashier_wallet
-            .mint(*XDRK_ID, token_supply, self.dao_wallet.bullas[0].0, recipient, &self.zk_bins)
+            .mint(*DRK_ID, token_supply, self.dao_wallet.bullas[0].0, recipient, &self.zk_bins)
             .unwrap();
 
         self.validate(&tx).unwrap();
@@ -582,7 +584,7 @@ impl DaoWallet {
             dao_quorum,
             dao_approval_ratio_quot,
             dao_approval_ratio_base,
-            gov_token_id: *GDRK_ID,
+            gov_token_id: *GOV_ID,
             dao_pubkey: self.keypair.public,
             dao_bulla_blind: self.bulla_blind,
             _signature_secret: self.signature_secret,
@@ -601,15 +603,19 @@ impl DaoWallet {
         Ok(())
     }
 
-    fn balances(&self) -> Result<u64> {
+    fn balances(&self) -> Result<FxHashMap<String, u64>> {
+        let mut ret: FxHashMap<String, u64> = FxHashMap::default();
         let mut balances = 0;
+        let token_id = "DRK".to_owned();
         for (coin, is_spent) in &self.own_coins {
             if *is_spent {
                 continue
             }
             balances += coin.note.value;
         }
-        Ok(balances)
+        ret.insert(token_id, balances);
+
+        Ok(ret)
     }
 
     fn store_proposal(&mut self, tx: &Transaction) -> Result<pallas::Base> {
@@ -753,7 +759,7 @@ impl DaoWallet {
                     // Change back to DAO
                     money_contract::transfer::wallet::BuilderOutputInfo {
                         value: total_input_value - proposal.amount,
-                        token_id: *XDRK_ID,
+                        token_id: *DRK_ID,
                         public: self.keypair.public,
                         serial: dao_serial,
                         coin_blind: dao_coin_blind,
@@ -855,13 +861,17 @@ impl MoneyWallet {
         Ok(())
     }
 
-    fn balances(&self) -> Result<u64> {
+    fn balances(&self) -> Result<FxHashMap<String, u64>> {
+        let mut ret: FxHashMap<String, u64> = FxHashMap::default();
         let mut balances = 0;
+        let token_id = "GOV".to_owned();
         for (coin, is_spent) in &self.own_coins {
             if *is_spent {}
             balances += coin.note.value;
         }
-        Ok(balances)
+        ret.insert(token_id, balances);
+
+        Ok(ret)
     }
 
     fn propose_tx(

+ 10 - 7
bin/dao/daod/src/rpc.rs

@@ -2,14 +2,16 @@ use std::sync::Arc;
 
 use async_std::sync::Mutex;
 use async_trait::async_trait;
+use fxhash::FxHashMap;
 use log::debug;
 use pasta_curves::{group::ff::PrimeField, pallas};
+use rand::rngs::OsRng;
 use std::str::FromStr;
 
 use serde_json::{json, Value};
 
 use darkfi::{
-    crypto::keypair::PublicKey,
+    crypto::keypair::{Keypair, PublicKey, SecretKey},
     rpc::{
         jsonrpc::{ErrorCode::*, JsonError, JsonRequest, JsonResponse, JsonResult},
         server::RequestHandler,
@@ -17,8 +19,9 @@ use darkfi::{
 };
 
 use crate::{
-    util::{parse_b58, GDRK_ID, XDRK_ID},
-    Client,
+    contract::money_contract::state::OwnCoin,
+    util::{parse_b58, DRK_ID, GOV_ID},
+    Client, MoneyWallet,
 };
 
 pub struct JsonRpcInterface {
@@ -77,7 +80,7 @@ impl JsonRpcInterface {
                 dao_quorum,
                 dao_approval_ratio_quot,
                 dao_approval_ratio_base,
-                *GDRK_ID,
+                *GOV_ID,
             )
             .unwrap();
 
@@ -164,7 +167,7 @@ impl JsonRpcInterface {
         let addr = params[1].as_str().unwrap();
         let dao_addr = PublicKey::from_str(addr).unwrap();
 
-        client.mint_treasury(*XDRK_ID, token_supply, dao_addr).unwrap();
+        client.mint_treasury(*DRK_ID, token_supply, dao_addr).unwrap();
 
         JsonResponse::new(json!("DAO treasury minted successfully."), id).into()
     }
@@ -192,7 +195,7 @@ impl JsonRpcInterface {
         let nym = params[0].as_str().unwrap().to_string();
         let value = params[1].as_u64().unwrap();
 
-        client.airdrop_user(value, *GDRK_ID, nym.clone()).unwrap();
+        client.airdrop_user(value, *GOV_ID, nym.clone()).unwrap();
 
         JsonResponse::new(json!("Tokens airdropped successfully."), id).into()
     }
@@ -207,7 +210,7 @@ impl JsonRpcInterface {
 
         let recv_addr = PublicKey::from_str(recipient).unwrap();
 
-        let proposal_bulla = client.propose(recv_addr, *XDRK_ID, amount, sender).unwrap();
+        let proposal_bulla = client.propose(recv_addr, *DRK_ID, amount, sender).unwrap();
         let bulla: String = bs58::encode(proposal_bulla.to_repr()).into_string();
 
         JsonResponse::new(json!(bulla), id).into()

+ 2 - 2
bin/dao/daod/src/util.rs

@@ -38,12 +38,12 @@ pub fn parse_b58(s: &str) -> std::result::Result<pallas::Base, darkfi::Error> {
 
 // The token of the DAO treasury.
 lazy_static! {
-    pub static ref XDRK_ID: pallas::Base = pallas::Base::random(&mut OsRng);
+    pub static ref DRK_ID: pallas::Base = pallas::Base::random(&mut OsRng);
 }
 
 // Governance tokens that are airdropped to users to operate the DAO.
 lazy_static! {
-    pub static ref GDRK_ID: pallas::Base = pallas::Base::random(&mut OsRng);
+    pub static ref GOV_ID: pallas::Base = pallas::Base::random(&mut OsRng);
 }
 
 #[derive(Eq, PartialEq, Debug)]