mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
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.
This commit is contained in:
@@ -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 (
|
||||
|
||||
@@ -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,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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(¶ms).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());
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user