Преглед изворни кода

drk: dao records sympliefied and dao mint call fee added

Removed dao_id and use the dao name as the identifier. Cleaned up all dao record structures. Fixed dao mint call and added its fee.
skoupidi пре 2 година
родитељ
комит
10ea889e31

+ 14 - 20
bin/drk/dao.sql

@@ -25,7 +25,7 @@
 --   $ drk dao import_dao DAO_NAME < dao.dat
 --   Imported DAO ccb8XXX8af6
 --
--- Where ccb8XXX8af6 is the DAO's bulla.
+-- Where ccb8XXX8af6 is the DAO's name.
 --
 -- Next one person will mint it on chain
 --
@@ -104,22 +104,16 @@
 PRAGMA foreign_keys = ON;
 
 CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_daos (
-	dao_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    name BLOB UNIQUE NOT NULL,
-    proposer_limit BLOB NOT NULL,
-    -- minimum threshold for total number of votes for proposal to pass.
-    -- If there's too little activity then it cannot pass.
-    quorum BLOB NOT NULL,
-    -- Needed ratio of yes/total for proposal to pass.
-    -- approval_ratio = approval_ratio_quot / approval_ratio_base
-    approval_ratio_base INTEGER NOT NULL,
-    approval_ratio_quot INTEGER NOT NULL,
-	gov_token_id BLOB NOT NULL,
-	secret BLOB NOT NULL,
-	bulla_blind BLOB NOT NULL,
-    -- these values are NULL until the DAO is minted on chain and received
-	leaf_position BLOB,
+    -- Name identifier of the DAO
+    name TEXT PRIMARY KEY UNIQUE NOT NULL,
+    -- DAO parameters
+    params BLOB NOT NULL,
+    -- These values are NULL until the DAO is minted on chain and received
+    -- Leaf position of the DAO in the Merkle tree of DAOs
+    leaf_position BLOB,
+    -- The transaction hash where the DAO was deployed
     tx_hash BLOB,
+    -- The call index in the transaction where the DAO was deployed
     call_index INTEGER
 );
 
@@ -131,7 +125,7 @@ CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_tree
 
 CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_proposals (
     proposal_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    dao_id INTEGER NOT NULL,
+    dao_name TEXT NOT NULL,
     -- Public key of person that would receive the funds
     recv_public BLOB NOT NULL,
     -- Amount of funds that would be sent
@@ -141,15 +135,15 @@ CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_prop
     bulla_blind BLOB NOT NULL,
     -- these values are NULL until the proposal is minted on chain
     -- and received by the DAO
-	leaf_position BLOB,
-	money_snapshot_tree BLOB,
+    leaf_position BLOB,
+    money_snapshot_tree BLOB,
     tx_hash BLOB,
     call_index INTEGER,
     -- this is NULL until we have voted on this proposal
     our_vote_id INTEGER UNIQUE,
 
     FOREIGN KEY(our_vote_id) REFERENCES Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_votes(vote_id) ON DELETE CASCADE ON UPDATE CASCADE,
-    FOREIGN KEY(dao_id) REFERENCES Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_daos(dao_id) ON DELETE CASCADE ON UPDATE CASCADE
+    FOREIGN KEY(dao_name) REFERENCES Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_daos(name) ON DELETE CASCADE ON UPDATE CASCADE
 );
 
 CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_votes (

+ 13 - 15
bin/drk/src/cli_util.rs

@@ -264,24 +264,23 @@ pub fn generate_completions(shell: &str) -> Result<()> {
 
     let name = Arg::with_name("name").help("Name identifier for the DAO");
 
-    let import =
-        SubCommand::with_name("import").about("Import DAO data from stdin").args(&vec![name]);
+    let import = SubCommand::with_name("import")
+        .about("Import DAO data from stdin")
+        .args(&vec![name.clone()]);
 
-    let name = Arg::with_name("dao-alias").help("Name identifier for the DAO (optional)");
+    let opt_name = Arg::with_name("dao-alias").help("Name identifier for the DAO (optional)");
 
     let list = SubCommand::with_name("list")
         .about("List imported DAOs (or info about a specific one)")
-        .args(&vec![name]);
-
-    let dao_alias = Arg::with_name("dao-alias").help("Name or numeric identifier for the DAO");
+        .args(&vec![opt_name]);
 
     let balance = SubCommand::with_name("balance")
         .about("Show the balance of a DAO")
-        .args(&vec![dao_alias.clone()]);
+        .args(&vec![name.clone()]);
 
     let mint = SubCommand::with_name("mint")
         .about("Mint an imported DAO on-chain")
-        .args(&vec![dao_alias.clone()]);
+        .args(&vec![name.clone()]);
 
     let recipient =
         Arg::with_name("recipient").help("Pubkey to send tokens to with proposal success");
@@ -292,17 +291,16 @@ pub fn generate_completions(shell: &str) -> Result<()> {
 
     let propose = SubCommand::with_name("propose")
         .about("Create a proposal for a DAO")
-        .args(&vec![dao_alias.clone(), recipient, amount, token]);
+        .args(&vec![name.clone(), recipient, amount, token]);
 
-    let proposals = SubCommand::with_name("proposals")
-        .about("List DAO proposals")
-        .args(&vec![dao_alias.clone()]);
+    let proposals =
+        SubCommand::with_name("proposals").about("List DAO proposals").args(&vec![name.clone()]);
 
     let proposal_id = Arg::with_name("proposal-id").help("Numeric identifier for the proposal");
 
     let proposal = SubCommand::with_name("proposal")
         .about("View a DAO proposal data")
-        .args(&vec![dao_alias.clone(), proposal_id.clone()]);
+        .args(&vec![name.clone(), proposal_id.clone()]);
 
     let vote = Arg::with_name("vote").help("Vote (0 for NO, 1 for YES)");
 
@@ -310,7 +308,7 @@ pub fn generate_completions(shell: &str) -> Result<()> {
         Arg::with_name("vote-weight").help("Vote weight (amount of governance tokens)");
 
     let vote = SubCommand::with_name("vote").about("Vote on a given proposal").args(&vec![
-        dao_alias.clone(),
+        name.clone(),
         proposal_id.clone(),
         vote,
         vote_weight,
@@ -318,7 +316,7 @@ pub fn generate_completions(shell: &str) -> Result<()> {
 
     let exec = SubCommand::with_name("exec")
         .about("Execute a DAO proposal")
-        .args(&vec![dao_alias, proposal_id]);
+        .args(&vec![name, proposal_id]);
 
     let dao = SubCommand::with_name("dao").about("DAO functionalities").subcommands(vec![
         create, view, import, list, balance, mint, propose, proposals, proposal, vote, exec,

Разлика између датотеке није приказан због своје велике величине
+ 290 - 387
bin/drk/src/dao.rs


+ 34 - 46
bin/drk/src/main.rs

@@ -335,20 +335,20 @@ enum DaoSubcmd {
 
     /// Show the balance of a DAO
     Balance {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
     },
 
     /// Mint an imported DAO on-chain
     Mint {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
     },
 
     /// Create a proposal for a DAO
     Propose {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
 
         /// Pubkey to send tokens to with proposal success
         recipient: String,
@@ -362,14 +362,14 @@ enum DaoSubcmd {
 
     /// List DAO proposals
     Proposals {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
     },
 
     /// View a DAO proposal data
     Proposal {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
 
         /// Numeric identifier for the proposal
         proposal_id: u64,
@@ -377,8 +377,8 @@ enum DaoSubcmd {
 
     /// Vote on a given proposal
     Vote {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
 
         /// Numeric identifier for the proposal
         proposal_id: u64,
@@ -392,8 +392,8 @@ enum DaoSubcmd {
 
     /// Execute a DAO proposal
     Exec {
-        /// Name or numeric identifier for the DAO
-        dao_alias: String,
+        /// Name identifier for the DAO
+        name: String,
 
         /// Numeric identifier for the proposal
         proposal_id: u64,
@@ -1039,9 +1039,9 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 };
 
                 let secret_key = SecretKey::random(&mut OsRng);
-                let bulla_blind = pallas::Base::random(&mut OsRng);
+                let bulla_blind = BaseBlind::random(&mut OsRng);
 
-                let params = DaoParams {
+                let params = DaoParams::new(
                     proposer_limit,
                     quorum,
                     approval_ratio_base,
@@ -1049,7 +1049,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                     gov_token_id,
                     secret_key,
                     bulla_blind,
-                };
+                );
 
                 let encoded = bs58::encode(&serialize_async(&params).await).into_string();
                 println!("{encoded}");
@@ -1074,7 +1074,6 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 let params: DaoParams = deserialize_async(&bytes).await?;
 
                 let drk = Drk::new(args.wallet_path, args.wallet_pass, None, ex).await?;
-
                 if let Err(e) = drk.import_dao(&name, params).await {
                     eprintln!("Failed to import DAO: {e:?}");
                     exit(2);
@@ -1093,11 +1092,9 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 Ok(())
             }
 
-            DaoSubcmd::Balance { dao_alias } => {
+            DaoSubcmd::Balance { name } => {
                 let drk = Drk::new(args.wallet_path, args.wallet_pass, None, ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
-
-                let balmap = match drk.dao_balance(dao_id).await {
+                let balmap = match drk.dao_balance(&name).await {
                     Ok(b) => b,
                     Err(e) => {
                         eprintln!("Failed to fetch DAO balance: {e:?}");
@@ -1139,23 +1136,22 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 Ok(())
             }
 
-            DaoSubcmd::Mint { dao_alias } => {
+            DaoSubcmd::Mint { name } => {
                 let drk =
                     Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
-
-                let tx = match drk.dao_mint(dao_id).await {
+                let tx = match drk.dao_mint(&name).await {
                     Ok(tx) => tx,
                     Err(e) => {
                         eprintln!("Failed to mint DAO: {e:?}");
                         exit(2);
                     }
                 };
+
                 println!("{}", base64::encode(&serialize_async(&tx).await));
                 Ok(())
             }
 
-            DaoSubcmd::Propose { dao_alias, recipient, amount, token } => {
+            DaoSubcmd::Propose { name, recipient, amount, token } => {
                 if let Err(e) = f64::from_str(&amount) {
                     eprintln!("Invalid amount: {e:?}");
                     exit(2);
@@ -1171,7 +1167,6 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
 
                 let drk =
                     Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
                 let token_id = match drk.get_token(token).await {
                     Ok(t) => t,
                     Err(e) => {
@@ -1180,7 +1175,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                     }
                 };
 
-                let tx = match drk.dao_propose(dao_id, rcpt, amount, token_id).await {
+                let tx = match drk.dao_propose(&name, rcpt, amount, token_id).await {
                     Ok(tx) => tx,
                     Err(e) => {
                         eprintln!("Failed to create DAO proposal: {e:?}");
@@ -1191,11 +1186,9 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 Ok(())
             }
 
-            DaoSubcmd::Proposals { dao_alias } => {
+            DaoSubcmd::Proposals { name } => {
                 let drk = Drk::new(args.wallet_path, args.wallet_pass, None, ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
-
-                let proposals = drk.get_dao_proposals(dao_id).await?;
+                let proposals = drk.get_dao_proposals(&name).await?;
 
                 for proposal in proposals {
                     println!("[{}] {:?}", proposal.id, proposal.bulla());
@@ -1204,11 +1197,9 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 Ok(())
             }
 
-            DaoSubcmd::Proposal { dao_alias, proposal_id } => {
+            DaoSubcmd::Proposal { name, proposal_id } => {
                 let drk = Drk::new(args.wallet_path, args.wallet_pass, None, ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
-
-                let proposals = drk.get_dao_proposals(dao_id).await?;
+                let proposals = drk.get_dao_proposals(&name).await?;
                 let Some(proposal) = proposals.iter().find(|x| x.id == proposal_id) else {
                     eprintln!("No such DAO proposal found");
                     exit(2);
@@ -1226,11 +1217,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 Ok(())
             }
 
-            DaoSubcmd::Vote { dao_alias, proposal_id, vote, vote_weight } => {
-                let drk =
-                    Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
-
+            DaoSubcmd::Vote { name, proposal_id, vote, vote_weight } => {
                 if let Err(e) = f64::from_str(&vote_weight) {
                     eprintln!("Invalid vote weight: {e:?}");
                     exit(2);
@@ -1243,7 +1230,9 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 }
                 let vote = vote != 0;
 
-                let tx = match drk.dao_vote(dao_id, proposal_id, vote, weight).await {
+                let drk =
+                    Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
+                let tx = match drk.dao_vote(&name, proposal_id, vote, weight).await {
                     Ok(tx) => tx,
                     Err(e) => {
                         eprintln!("Failed to create DAO Vote transaction: {e:?}");
@@ -1258,11 +1247,10 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 Ok(())
             }
 
-            DaoSubcmd::Exec { dao_alias, proposal_id } => {
+            DaoSubcmd::Exec { name, proposal_id } => {
                 let drk =
                     Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
-                let dao_id = drk.get_dao_id(&dao_alias).await?;
-                let dao = drk.get_dao_by_id(dao_id).await?;
+                let dao = drk.get_dao_by_name(&name).await?;
                 let proposal = drk.get_dao_proposal_by_id(proposal_id).await?;
                 assert!(proposal.dao_bulla == dao.bulla());
 

+ 1 - 1
contrib/localnet/darkfid-single-node/README.md

@@ -65,7 +65,7 @@ of the guide can be added for future regressions.
 | 20 | DAO view                  | dao view                                         | Pass               |
 | 21 | DAO import                | dao import                                       | Pass               |
 | 22 | DAO list                  | dao list                                         | Pass               |
-| 23 | DAO mint                  | dao mint {DAO}                                   | Failure: needs #19 |
+| 23 | DAO mint                  | dao mint {DAO}                                   | Pass               |
 | 24 | DAO balance               | dao balance {DAO}                                | Failure: needs #19 |
 | 25 | DAO propose               | dao propose {DAO} {ADDR} {AMOUNT} {TOKEN}        | Failure: needs #19 |
 | 26 | DAO proposals retrieval   | dao proposals {DAO}                              | Failure: needs #25 |

+ 6 - 0
src/contract/dao/src/model.rs

@@ -37,12 +37,18 @@ use darkfi_serial::async_trait;
 // ANCHOR: dao
 /// DAOs are represented on chain as a commitment to this object
 pub struct Dao {
+    /// The minimum amount of governance tokens needed to open a proposal
     pub proposer_limit: u64,
+    /// Minimal threshold of participating total tokens needed for a proposal to pass
     pub quorum: u64,
+    /// The ratio of winning/total votes needed for a proposal to pass
     pub approval_ratio_quot: u64,
     pub approval_ratio_base: u64,
+    /// DAO's governance token ID
     pub gov_token_id: TokenId,
+    /// Public key of the DAO
     pub public_key: PublicKey,
+    /// DAO bulla blind
     pub bulla_blind: BaseBlind,
 }
 // ANCHOR_END: dao

Неке датотеке нису приказане због велике количине промена