diff --git a/.gitignore b/.gitignore index 95b020d8f..13d555315 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ /lilith /darkwiki /darkwikid +/zktool TAGS diff --git a/README.md b/README.md index cf707b0de..cb8fc3d64 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ for the P2P IRC daemon. This project requires the Rust compiler to be installed. Please visit [Rustup](https://rustup.rs/) for instructions. -Minimum Rust version supported is **1.65.0 (stable)**. +Minimum Rust version supported is **1.67.0 (stable)**. The following dependencies are also required: @@ -49,7 +49,7 @@ following to install the required dependencies: ```shell # apt-get update -# apt-get install -y git make jq gcc pkg-config libssl-dev +# apt-get install -y git make jq gcc pkg-config ``` Alternatively, users can try using the automated script under `contrib` @@ -64,12 +64,12 @@ and install dependencies accordingly. In case it does not find your package manager, please consider adding support for it into the script and sending a patch. -To build the necessary binaries, we can just clone the repo, and use -the provided Makefile to build the project: +To build the necessary binaries, we can just clone the repo, checkout +to the latest tag, and use the provided Makefile to build the project: ```shell % git clone https://github.com/darkrenaissance/darkfi -% cd darkfi/ +% cd darkfi && git checkout v0.4.0 % make ``` @@ -91,12 +91,6 @@ in order for them to spawn a config file, which you can then review. # make install ``` -## Bash Completion -This will add the options auto completion of `drk` and `darkfid`. -```shell -% echo source \$(pwd)/contrib/auto-complete >> ~/.bashrc -``` - ### Examples and usage See the [DarkFi book](https://darkrenaissance.github.io/darkfi) diff --git a/bin/drk/src/main.rs b/bin/drk/src/main.rs index 19f431bbd..c7487e903 100644 --- a/bin/drk/src/main.rs +++ b/bin/drk/src/main.rs @@ -875,7 +875,7 @@ async fn main() -> Result<()> { let drk = Drk::new(args.endpoint).await?; let dao = drk.get_dao_by_id(dao_id).await?; let proposal = drk.get_dao_proposal_by_id(proposal_id).await?; - assert!(proposal.id == dao.id); + assert!(proposal.dao_bulla == dao.bulla()); let tx = drk .dao_exec(dao, proposal) diff --git a/bin/drk/src/rpc_blockchain.rs b/bin/drk/src/rpc_blockchain.rs index e105fa0cb..f75440bf7 100644 --- a/bin/drk/src/rpc_blockchain.rs +++ b/bin/drk/src/rpc_blockchain.rs @@ -206,6 +206,8 @@ impl Drk { self.reset_money_coins().await?; self.reset_dao_trees().await?; self.reset_daos().await?; + self.reset_dao_proposals().await?; + self.reset_dao_votes().await?; 0 } else { self.last_scanned_slot().await? diff --git a/bin/drk/src/rpc_dao.rs b/bin/drk/src/rpc_dao.rs index de08ce2e3..dc71098df 100644 --- a/bin/drk/src/rpc_dao.rs +++ b/bin/drk/src/rpc_dao.rs @@ -385,6 +385,7 @@ impl Drk { /// This function is really bad but I'm also really tired and annoyed. pub async fn dao_exec(&self, dao: Dao, proposal: DaoProposal) -> Result { let dao_bulla = dao.bulla(); + eprintln!("Fetching proposal's votes"); let votes = self.get_dao_proposal_votes(proposal.id).await?; // Find the treasury coins that can be used for this proposal diff --git a/bin/drk/src/wallet_dao.rs b/bin/drk/src/wallet_dao.rs index 09510b7bc..89ba9e13f 100644 --- a/bin/drk/src/wallet_dao.rs +++ b/bin/drk/src/wallet_dao.rs @@ -405,6 +405,30 @@ impl Drk { Ok(()) } + pub async fn reset_dao_proposals(&self) -> Result<()> { + eprintln!("Resetting DAO proposals"); + let query = format!("DELETE FROM {};", DAO_PROPOSALS_TABLE); + + let params = json!([query]); + + let req = JsonRequest::new("wallet.exec_sql", params); + let _ = self.rpc_client.request(req).await?; + + Ok(()) + } + + pub async fn reset_dao_votes(&self) -> Result<()> { + eprintln!("Resetting DAO votes"); + let query = format!("DELETE FROM {};", DAO_VOTES_TABLE); + + let params = json!([query]); + + let req = JsonRequest::new("wallet.exec_sql", params); + let _ = self.rpc_client.request(req).await?; + + Ok(()) + } + /// Import given DAO params into the wallet with a given name. pub async fn import_dao(&self, dao_name: String, dao_params: DaoParams) -> Result<()> { // First let's check if we've imported this DAO with the given name before. @@ -876,7 +900,8 @@ impl Drk { let id: u64 = serde_json::from_value(row[0].clone())?; let proposal_id: u64 = serde_json::from_value(row[1].clone())?; - let vote_option: bool = serde_json::from_value(row[2].clone())?; + let vote_option: u32 = serde_json::from_value(row[2].clone())?; + let vote_option = vote_option != 0; let yes_vote_blind_bytes: Vec = serde_json::from_value(row[3].clone())?; let yes_vote_blind = deserialize(&yes_vote_blind_bytes)?; @@ -1209,7 +1234,7 @@ impl Drk { QueryType::Integer as u8, vote.proposal_id, QueryType::Integer as u8, - vote.vote_option, + vote.vote_option as u64, QueryType::Blob as u8, serialize(&vote.yes_vote_blind), QueryType::Blob as u8, diff --git a/src/contract/dao/src/dao_client/mod.rs b/src/contract/dao/src/dao_client/mod.rs index a894493fe..85cf94319 100644 --- a/src/contract/dao/src/dao_client/mod.rs +++ b/src/contract/dao/src/dao_client/mod.rs @@ -80,5 +80,8 @@ pub const DAO_VOTES_TABLE: &str = "dao_votes"; pub const DAO_VOTES_COL_VOTE_ID: &str = "vote_id"; pub const DAO_VOTES_COL_PROPOSAL_ID: &str = "proposal_id"; pub const DAO_VOTES_COL_VOTE_OPTION: &str = "vote_option"; +pub const DAO_VOTES_COL_YES_VOTE_BLIND: &str = "yes_vote_blind"; +pub const DAO_VOTES_COL_ALL_VOTE_VALUE: &str = "all_vote_value"; +pub const DAO_VOTES_COL_ALL_VOTE_BLIND: &str = "all_vote_blind"; pub const DAO_VOTES_COL_TX_HASH: &str = "tx_hash"; pub const DAO_VOTES_COL_CALL_INDEX: &str = "call_index"; diff --git a/src/contract/dao/wallet.sql b/src/contract/dao/wallet.sql index 6bc603bc0..2f78bc7fb 100644 --- a/src/contract/dao/wallet.sql +++ b/src/contract/dao/wallet.sql @@ -106,10 +106,10 @@ PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS dao_daos ( dao_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name BLOB UNIQUE NOT NULL, - proposer_limit INTEGER 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 INTEGER NOT NULL, + 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, @@ -156,6 +156,9 @@ CREATE TABLE IF NOT EXISTS dao_votes ( vote_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, proposal_id INTEGER NOT NULL, vote_option INTEGER NOT NULL, + yes_vote_blind BLOB NOT NULL, + all_vote_value BLOB NOT NULL, + all_vote_blind BLOB NOT NULL, -- these values are NULL until the vote is minted on chain -- and received by the DAO tx_hash BLOB, diff --git a/src/contract/money/src/client.rs b/src/contract/money/src/client.rs index 253ac64f5..6b3ecc51e 100644 --- a/src/contract/money/src/client.rs +++ b/src/contract/money/src/client.rs @@ -1004,10 +1004,10 @@ pub fn build_transfer_tx( // A hacky way to zeroize spend hooks for the change outputs let (scoped_spend_hook, scoped_user_data) = { - if i >= outputs.len() { - (pallas::Base::zero(), pallas::Base::zero()) - } else { + if i >= change_outputs.len() { (spend_hook, user_data) + } else { + (pallas::Base::zero(), pallas::Base::zero()) } }; @@ -1056,7 +1056,6 @@ pub fn build_transfer_tx( // Now we should have all the params, zk proofs, and signature secrets. // We return it all and let the caller deal with it. - Ok((params, zk_proofs, signature_secrets, spent_coins)) }