mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
drk: moved contracts sql stuff from their client to drk directly
Also prefixed table name with their corresponding contract idfff
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2655,6 +2655,7 @@ dependencies = [
|
||||
"darkfi_dao_contract",
|
||||
"darkfi_money_contract",
|
||||
"easy-parallel",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"prettytable-rs",
|
||||
"rand 0.8.5",
|
||||
|
||||
@@ -19,6 +19,7 @@ darkfi-serial = {path = "../../src/serial"}
|
||||
# Misc
|
||||
blake3 = "1.5.0"
|
||||
bs58 = "0.5.0"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.20"
|
||||
prettytable-rs = "0.10.0"
|
||||
rand = "0.8.5"
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dao_daos (
|
||||
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,
|
||||
@@ -124,12 +124,12 @@ CREATE TABLE IF NOT EXISTS dao_daos (
|
||||
);
|
||||
|
||||
-- The merkle tree containing DAO bullas
|
||||
CREATE TABLE IF NOT EXISTS dao_trees (
|
||||
CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_trees (
|
||||
daos_tree BLOB NOT NULL,
|
||||
proposals_tree BLOB NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dao_proposals (
|
||||
CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_proposals (
|
||||
proposal_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
dao_id INTEGER NOT NULL,
|
||||
-- Public key of person that would receive the funds
|
||||
@@ -152,7 +152,7 @@ CREATE TABLE IF NOT EXISTS dao_proposals (
|
||||
FOREIGN KEY(dao_id) REFERENCES dao_daos(dao_id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dao_votes (
|
||||
CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_votes (
|
||||
vote_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
proposal_id INTEGER NOT NULL,
|
||||
vote_option INTEGER NOT NULL,
|
||||
@@ -3,17 +3,17 @@
|
||||
-- TODO: The tables should be prefixed with ContractId to prevent collision
|
||||
|
||||
-- Arbitrary info that is potentially useful
|
||||
CREATE TABLE IF NOT EXISTS money_info (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_info (
|
||||
last_scanned_slot INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- The Merkle tree containing coins
|
||||
CREATE TABLE IF NOT EXISTS money_tree (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_tree (
|
||||
tree BLOB NOT NULL
|
||||
);
|
||||
|
||||
-- The keypairs in our wallet
|
||||
CREATE TABLE IF NOT EXISTS money_keys (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_keys (
|
||||
key_id INTEGER PRIMARY KEY NOT NULL,
|
||||
is_default INTEGER NOT NULL,
|
||||
public BLOB NOT NULL,
|
||||
@@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS money_keys (
|
||||
);
|
||||
|
||||
-- The coins we have the information to and can spend
|
||||
CREATE TABLE IF NOT EXISTS money_coins (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_coins (
|
||||
coin BLOB PRIMARY KEY NOT NULL,
|
||||
is_spent INTEGER NOT NULL,
|
||||
value BLOB NOT NULL,
|
||||
@@ -38,19 +38,19 @@ CREATE TABLE IF NOT EXISTS money_coins (
|
||||
);
|
||||
|
||||
-- Arbitrary tokens
|
||||
CREATE TABLE IF NOT EXISTS money_tokens (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_tokens (
|
||||
mint_authority BLOB PRIMARY KEY NOT NULL,
|
||||
token_id BLOB NOT NULL,
|
||||
is_frozen INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- The token aliases in our wallet
|
||||
CREATE TABLE IF NOT EXISTS money_aliases (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_aliases (
|
||||
alias BLOB PRIMARY KEY NOT NULL,
|
||||
token_id BLOB NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS transactions_history (
|
||||
CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_transactions_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
transaction_hash TEXT UNIQUE NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
use std::{collections::HashMap, fmt};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use rand::rngs::OsRng;
|
||||
use rusqlite::types::Value;
|
||||
|
||||
@@ -29,22 +30,7 @@ use darkfi::{
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_dao_contract::{
|
||||
client::{
|
||||
make_mint_call, DaoProposeCall, DaoProposeStakeInput, DaoVoteCall, DaoVoteInput,
|
||||
DAO_DAOS_COL_APPROVAL_RATIO_BASE, DAO_DAOS_COL_APPROVAL_RATIO_QUOT,
|
||||
DAO_DAOS_COL_BULLA_BLIND, DAO_DAOS_COL_CALL_INDEX, DAO_DAOS_COL_DAO_ID,
|
||||
DAO_DAOS_COL_GOV_TOKEN_ID, DAO_DAOS_COL_LEAF_POSITION, DAO_DAOS_COL_NAME,
|
||||
DAO_DAOS_COL_PROPOSER_LIMIT, DAO_DAOS_COL_QUORUM, DAO_DAOS_COL_SECRET,
|
||||
DAO_DAOS_COL_TX_HASH, DAO_DAOS_TABLE, DAO_PROPOSALS_COL_AMOUNT,
|
||||
DAO_PROPOSALS_COL_BULLA_BLIND, DAO_PROPOSALS_COL_CALL_INDEX, DAO_PROPOSALS_COL_DAO_ID,
|
||||
DAO_PROPOSALS_COL_LEAF_POSITION, DAO_PROPOSALS_COL_MONEY_SNAPSHOT_TREE,
|
||||
DAO_PROPOSALS_COL_PROPOSAL_ID, DAO_PROPOSALS_COL_RECV_PUBLIC,
|
||||
DAO_PROPOSALS_COL_SENDCOIN_TOKEN_ID, DAO_PROPOSALS_COL_TX_HASH, DAO_PROPOSALS_TABLE,
|
||||
DAO_TREES_COL_DAOS_TREE, DAO_TREES_COL_PROPOSALS_TREE, DAO_TREES_TABLE,
|
||||
DAO_VOTES_COL_ALL_VOTE_BLIND, DAO_VOTES_COL_ALL_VOTE_VALUE, DAO_VOTES_COL_CALL_INDEX,
|
||||
DAO_VOTES_COL_PROPOSAL_ID, DAO_VOTES_COL_TX_HASH, DAO_VOTES_COL_VOTE_OPTION,
|
||||
DAO_VOTES_COL_YES_VOTE_BLIND, DAO_VOTES_TABLE,
|
||||
},
|
||||
client::{make_mint_call, DaoProposeCall, DaoProposeStakeInput, DaoVoteCall, DaoVoteInput},
|
||||
model::{DaoAuthCall, DaoBulla, DaoMintParams, DaoProposeParams, DaoVoteParams},
|
||||
DaoFunction, DAO_CONTRACT_ZKAS_DAO_MINT_NS, DAO_CONTRACT_ZKAS_DAO_PROPOSE_INPUT_NS,
|
||||
DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS, DAO_CONTRACT_ZKAS_DAO_VOTE_INPUT_NS,
|
||||
@@ -73,6 +59,62 @@ use crate::{
|
||||
Drk,
|
||||
};
|
||||
|
||||
// Wallet SQL table constant names. These have to represent the `wallet.sql`
|
||||
// SQL schema. Table names are prefixed with the contract ID to avoid collisions.
|
||||
lazy_static! {
|
||||
pub static ref DAO_DAOS_TABLE: String = format!("{}_dao_daos", DAO_CONTRACT_ID.to_string());
|
||||
pub static ref DAO_TREES_TABLE: String = format!("{}_dao_trees", DAO_CONTRACT_ID.to_string());
|
||||
pub static ref DAO_COINS_TABLE: String = format!("{}_dao_coins", DAO_CONTRACT_ID.to_string());
|
||||
pub static ref DAO_PROPOSALS_TABLE: String =
|
||||
format!("{}_dao_proposals", DAO_CONTRACT_ID.to_string());
|
||||
pub static ref DAO_VOTES_TABLE: String = format!("{}_dao_votes", DAO_CONTRACT_ID.to_string());
|
||||
}
|
||||
|
||||
// DAO_DAOS_TABLE
|
||||
pub const DAO_DAOS_COL_DAO_ID: &str = "dao_id";
|
||||
pub const DAO_DAOS_COL_NAME: &str = "name";
|
||||
pub const DAO_DAOS_COL_PROPOSER_LIMIT: &str = "proposer_limit";
|
||||
pub const DAO_DAOS_COL_QUORUM: &str = "quorum";
|
||||
pub const DAO_DAOS_COL_APPROVAL_RATIO_BASE: &str = "approval_ratio_base";
|
||||
pub const DAO_DAOS_COL_APPROVAL_RATIO_QUOT: &str = "approval_ratio_quot";
|
||||
pub const DAO_DAOS_COL_GOV_TOKEN_ID: &str = "gov_token_id";
|
||||
pub const DAO_DAOS_COL_SECRET: &str = "secret";
|
||||
pub const DAO_DAOS_COL_BULLA_BLIND: &str = "bulla_blind";
|
||||
pub const DAO_DAOS_COL_LEAF_POSITION: &str = "leaf_position";
|
||||
pub const DAO_DAOS_COL_TX_HASH: &str = "tx_hash";
|
||||
pub const DAO_DAOS_COL_CALL_INDEX: &str = "call_index";
|
||||
|
||||
// DAO_TREES_TABLE
|
||||
pub const DAO_TREES_COL_DAOS_TREE: &str = "daos_tree";
|
||||
pub const DAO_TREES_COL_PROPOSALS_TREE: &str = "proposals_tree";
|
||||
|
||||
// DAO_COINS_TABLE
|
||||
pub const _DAO_COINS_COL_COIN_ID: &str = "coin_id";
|
||||
pub const _DAO_COINS_COL_DAO_ID: &str = "dao_id";
|
||||
|
||||
// DAO_PROPOSALS_TABLE
|
||||
pub const DAO_PROPOSALS_COL_PROPOSAL_ID: &str = "proposal_id";
|
||||
pub const DAO_PROPOSALS_COL_DAO_ID: &str = "dao_id";
|
||||
pub const DAO_PROPOSALS_COL_RECV_PUBLIC: &str = "recv_public";
|
||||
pub const DAO_PROPOSALS_COL_AMOUNT: &str = "amount";
|
||||
pub const DAO_PROPOSALS_COL_SENDCOIN_TOKEN_ID: &str = "sendcoin_token_id";
|
||||
pub const DAO_PROPOSALS_COL_BULLA_BLIND: &str = "bulla_blind";
|
||||
pub const DAO_PROPOSALS_COL_LEAF_POSITION: &str = "leaf_position";
|
||||
pub const DAO_PROPOSALS_COL_MONEY_SNAPSHOT_TREE: &str = "money_snapshot_tree";
|
||||
pub const DAO_PROPOSALS_COL_TX_HASH: &str = "tx_hash";
|
||||
pub const DAO_PROPOSALS_COL_CALL_INDEX: &str = "call_index";
|
||||
pub const _DAO_PROPOSALS_COL_OUR_VOTE_ID: &str = "our_vote_id";
|
||||
|
||||
// DAO_VOTES_TABLE
|
||||
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";
|
||||
|
||||
#[derive(SerialEncodable, SerialDecodable, Clone)]
|
||||
pub struct DaoProposalInfo {
|
||||
pub dest: PublicKey,
|
||||
@@ -319,7 +361,7 @@ impl Drk {
|
||||
/// Initialize wallet with tables for the DAO contract.
|
||||
pub async fn initialize_dao(&self) -> WalletDbResult<()> {
|
||||
// Initialize DAO wallet schema
|
||||
let wallet_schema = include_str!("../../../src/contract/dao/wallet.sql");
|
||||
let wallet_schema = include_str!("../dao.sql");
|
||||
self.wallet.exec_batch_sql(wallet_schema).await?;
|
||||
|
||||
// Check if we have to initialize the Merkle trees.
|
||||
@@ -327,7 +369,11 @@ impl Drk {
|
||||
// a bit better and safer.
|
||||
// For now, on success, we don't care what's returned, but in the future
|
||||
// we should actually check it.
|
||||
if self.wallet.query_single(DAO_TREES_TABLE, &[DAO_TREES_COL_DAOS_TREE], &[]).await.is_err()
|
||||
if self
|
||||
.wallet
|
||||
.query_single(&DAO_TREES_TABLE, &[DAO_TREES_COL_DAOS_TREE], &[])
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
eprintln!("Initializing DAO Merkle trees");
|
||||
let tree = MerkleTree::new(100);
|
||||
@@ -345,13 +391,13 @@ impl Drk {
|
||||
proposals_tree: &MerkleTree,
|
||||
) -> WalletDbResult<()> {
|
||||
// First we remove old records
|
||||
let query = format!("DELETE FROM {};", DAO_TREES_TABLE);
|
||||
let query = format!("DELETE FROM {};", *DAO_TREES_TABLE);
|
||||
self.wallet.exec_sql(&query, &[]).await?;
|
||||
|
||||
// then we insert the new one
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}) VALUES (?1, ?2);",
|
||||
DAO_TREES_TABLE, DAO_TREES_COL_DAOS_TREE, DAO_TREES_COL_PROPOSALS_TREE,
|
||||
*DAO_TREES_TABLE, DAO_TREES_COL_DAOS_TREE, DAO_TREES_COL_PROPOSALS_TREE,
|
||||
);
|
||||
self.wallet
|
||||
.exec_sql(&query, rusqlite::params![serialize(daos_tree), serialize(proposals_tree)])
|
||||
@@ -360,7 +406,7 @@ impl Drk {
|
||||
|
||||
/// Fetch DAO Merkle trees from the wallet.
|
||||
pub async fn get_dao_trees(&self) -> Result<(MerkleTree, MerkleTree)> {
|
||||
let row = match self.wallet.query_single(DAO_TREES_TABLE, &[], &[]).await {
|
||||
let row = match self.wallet.query_single(&DAO_TREES_TABLE, &[], &[]).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
@@ -395,7 +441,7 @@ impl Drk {
|
||||
|
||||
/// Fetch all known DAOs from the wallet.
|
||||
pub async fn get_daos(&self) -> Result<Vec<Dao>> {
|
||||
let rows = match self.wallet.query_multiple(DAO_DAOS_TABLE, &[], &[]).await {
|
||||
let rows = match self.wallet.query_multiple(&DAO_DAOS_TABLE, &[], &[]).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!("[get_daos] DAOs retrieval failed: {e:?}")))
|
||||
@@ -611,7 +657,7 @@ impl Drk {
|
||||
let rows = match self
|
||||
.wallet
|
||||
.query_multiple(
|
||||
DAO_PROPOSALS_TABLE,
|
||||
&DAO_PROPOSALS_TABLE,
|
||||
&[],
|
||||
convert_named_params! {(DAO_PROPOSALS_COL_DAO_ID, dao_id)},
|
||||
)
|
||||
@@ -822,7 +868,7 @@ impl Drk {
|
||||
for dao in daos {
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1, {} = ?2, {} = ?3 WHERE {} = {};",
|
||||
DAO_DAOS_TABLE,
|
||||
*DAO_DAOS_TABLE,
|
||||
DAO_DAOS_COL_LEAF_POSITION,
|
||||
DAO_DAOS_COL_TX_HASH,
|
||||
DAO_DAOS_COL_CALL_INDEX,
|
||||
@@ -849,7 +895,7 @@ impl Drk {
|
||||
for dao in daos {
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1, {} = ?2, {} = ?3 WHERE {} = {};",
|
||||
DAO_DAOS_TABLE,
|
||||
*DAO_DAOS_TABLE,
|
||||
DAO_DAOS_COL_LEAF_POSITION,
|
||||
DAO_DAOS_COL_TX_HASH,
|
||||
DAO_DAOS_COL_CALL_INDEX,
|
||||
@@ -877,7 +923,7 @@ impl Drk {
|
||||
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}, {}, {}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9);",
|
||||
DAO_PROPOSALS_TABLE,
|
||||
*DAO_PROPOSALS_TABLE,
|
||||
DAO_PROPOSALS_COL_DAO_ID,
|
||||
DAO_PROPOSALS_COL_RECV_PUBLIC,
|
||||
DAO_PROPOSALS_COL_AMOUNT,
|
||||
@@ -923,7 +969,7 @@ impl Drk {
|
||||
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);",
|
||||
DAO_VOTES_TABLE,
|
||||
*DAO_VOTES_TABLE,
|
||||
DAO_VOTES_COL_PROPOSAL_ID,
|
||||
DAO_VOTES_COL_VOTE_OPTION,
|
||||
DAO_VOTES_COL_YES_VOTE_BLIND,
|
||||
@@ -983,14 +1029,14 @@ impl Drk {
|
||||
/// Reset all DAO proposals in the wallet.
|
||||
pub async fn reset_dao_proposals(&self) -> WalletDbResult<()> {
|
||||
eprintln!("Resetting DAO proposals");
|
||||
let query = format!("DELETE FROM {};", DAO_PROPOSALS_TABLE);
|
||||
let query = format!("DELETE FROM {};", *DAO_PROPOSALS_TABLE);
|
||||
self.wallet.exec_sql(&query, &[]).await
|
||||
}
|
||||
|
||||
/// Reset all DAO votes in the wallet.
|
||||
pub async fn reset_dao_votes(&self) -> WalletDbResult<()> {
|
||||
eprintln!("Resetting DAO votes");
|
||||
let query = format!("DELETE FROM {};", DAO_VOTES_TABLE);
|
||||
let query = format!("DELETE FROM {};", *DAO_VOTES_TABLE);
|
||||
self.wallet.exec_sql(&query, &[]).await
|
||||
}
|
||||
|
||||
@@ -1011,7 +1057,7 @@ impl Drk {
|
||||
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}, {}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);",
|
||||
DAO_DAOS_TABLE,
|
||||
*DAO_DAOS_TABLE,
|
||||
DAO_DAOS_COL_NAME,
|
||||
DAO_DAOS_COL_PROPOSER_LIMIT,
|
||||
DAO_DAOS_COL_QUORUM,
|
||||
@@ -1049,7 +1095,7 @@ impl Drk {
|
||||
let row = match self
|
||||
.wallet
|
||||
.query_single(
|
||||
DAO_DAOS_TABLE,
|
||||
&DAO_DAOS_TABLE,
|
||||
&[DAO_DAOS_COL_DAO_ID],
|
||||
convert_named_params! {(DAO_DAOS_COL_NAME, alias_filter)},
|
||||
)
|
||||
@@ -1155,7 +1201,7 @@ impl Drk {
|
||||
let row = match self
|
||||
.wallet
|
||||
.query_single(
|
||||
DAO_PROPOSALS_TABLE,
|
||||
&DAO_PROPOSALS_TABLE,
|
||||
&[],
|
||||
convert_named_params! {(DAO_PROPOSALS_COL_PROPOSAL_ID, proposal_id)},
|
||||
)
|
||||
@@ -1187,7 +1233,7 @@ impl Drk {
|
||||
let rows = match self
|
||||
.wallet
|
||||
.query_multiple(
|
||||
DAO_VOTES_TABLE,
|
||||
&DAO_VOTES_TABLE,
|
||||
&[],
|
||||
convert_named_params! {(DAO_VOTES_COL_PROPOSAL_ID, proposal_id)},
|
||||
)
|
||||
|
||||
@@ -18,23 +18,13 @@
|
||||
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use rand::rngs::OsRng;
|
||||
use rusqlite::types::Value;
|
||||
|
||||
use darkfi::{tx::Transaction, zk::halo2::Field, Error, Result};
|
||||
use darkfi_money_contract::{
|
||||
client::{
|
||||
MoneyNote, OwnCoin, MONEY_ALIASES_COL_ALIAS, MONEY_ALIASES_COL_TOKEN_ID,
|
||||
MONEY_ALIASES_TABLE, MONEY_COINS_COL_COIN, MONEY_COINS_COL_IS_SPENT,
|
||||
MONEY_COINS_COL_LEAF_POSITION, MONEY_COINS_COL_MEMO, MONEY_COINS_COL_NULLIFIER,
|
||||
MONEY_COINS_COL_SECRET, MONEY_COINS_COL_SERIAL, MONEY_COINS_COL_SPEND_HOOK,
|
||||
MONEY_COINS_COL_TOKEN_BLIND, MONEY_COINS_COL_TOKEN_ID, MONEY_COINS_COL_USER_DATA,
|
||||
MONEY_COINS_COL_VALUE, MONEY_COINS_COL_VALUE_BLIND, MONEY_COINS_TABLE,
|
||||
MONEY_INFO_COL_LAST_SCANNED_SLOT, MONEY_INFO_TABLE, MONEY_KEYS_COL_IS_DEFAULT,
|
||||
MONEY_KEYS_COL_KEY_ID, MONEY_KEYS_COL_PUBLIC, MONEY_KEYS_COL_SECRET, MONEY_KEYS_TABLE,
|
||||
MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_TOKEN_ID, MONEY_TOKENS_TABLE,
|
||||
MONEY_TREE_COL_TREE, MONEY_TREE_TABLE,
|
||||
},
|
||||
client::{MoneyNote, OwnCoin},
|
||||
model::{
|
||||
Coin, MoneyTokenFreezeParamsV1, MoneyTokenMintParamsV1, MoneyTransferParamsV1, Output,
|
||||
},
|
||||
@@ -56,13 +46,66 @@ use crate::{
|
||||
kaching, Drk,
|
||||
};
|
||||
|
||||
// Wallet SQL table constant names. These have to represent the `wallet.sql`
|
||||
// SQL schema. Table names are prefixed with the contract ID to avoid collisions.
|
||||
lazy_static! {
|
||||
pub static ref MONEY_INFO_TABLE: String =
|
||||
format!("{}_money_info", MONEY_CONTRACT_ID.to_string());
|
||||
pub static ref MONEY_TREE_TABLE: String =
|
||||
format!("{}_money_tree", MONEY_CONTRACT_ID.to_string());
|
||||
pub static ref MONEY_KEYS_TABLE: String =
|
||||
format!("{}_money_keys", MONEY_CONTRACT_ID.to_string());
|
||||
pub static ref MONEY_COINS_TABLE: String =
|
||||
format!("{}_money_coins", MONEY_CONTRACT_ID.to_string());
|
||||
pub static ref MONEY_TOKENS_TABLE: String =
|
||||
format!("{}_money_tokens", MONEY_CONTRACT_ID.to_string());
|
||||
pub static ref MONEY_ALIASES_TABLE: String =
|
||||
format!("{}_money_aliases", MONEY_CONTRACT_ID.to_string());
|
||||
}
|
||||
|
||||
// MONEY_INFO_TABLE
|
||||
pub const MONEY_INFO_COL_LAST_SCANNED_SLOT: &str = "last_scanned_slot";
|
||||
|
||||
// MONEY_TREE_TABLE
|
||||
pub const MONEY_TREE_COL_TREE: &str = "tree";
|
||||
|
||||
// MONEY_KEYS_TABLE
|
||||
pub const MONEY_KEYS_COL_KEY_ID: &str = "key_id";
|
||||
pub const MONEY_KEYS_COL_IS_DEFAULT: &str = "is_default";
|
||||
pub const MONEY_KEYS_COL_PUBLIC: &str = "public";
|
||||
pub const MONEY_KEYS_COL_SECRET: &str = "secret";
|
||||
|
||||
// MONEY_COINS_TABLE
|
||||
pub const MONEY_COINS_COL_COIN: &str = "coin";
|
||||
pub const MONEY_COINS_COL_IS_SPENT: &str = "is_spent";
|
||||
pub const MONEY_COINS_COL_SERIAL: &str = "serial";
|
||||
pub const MONEY_COINS_COL_VALUE: &str = "value";
|
||||
pub const MONEY_COINS_COL_TOKEN_ID: &str = "token_id";
|
||||
pub const MONEY_COINS_COL_SPEND_HOOK: &str = "spend_hook";
|
||||
pub const MONEY_COINS_COL_USER_DATA: &str = "user_data";
|
||||
pub const MONEY_COINS_COL_VALUE_BLIND: &str = "value_blind";
|
||||
pub const MONEY_COINS_COL_TOKEN_BLIND: &str = "token_blind";
|
||||
pub const MONEY_COINS_COL_SECRET: &str = "secret";
|
||||
pub const MONEY_COINS_COL_NULLIFIER: &str = "nullifier";
|
||||
pub const MONEY_COINS_COL_LEAF_POSITION: &str = "leaf_position";
|
||||
pub const MONEY_COINS_COL_MEMO: &str = "memo";
|
||||
|
||||
// MONEY_TOKENS_TABLE
|
||||
pub const MONEY_TOKENS_COL_MINT_AUTHORITY: &str = "mint_authority";
|
||||
pub const MONEY_TOKENS_COL_TOKEN_ID: &str = "token_id";
|
||||
pub const MONEY_TOKENS_COL_IS_FROZEN: &str = "is_frozen";
|
||||
|
||||
// MONEY_ALIASES_TABLE
|
||||
pub const MONEY_ALIASES_COL_ALIAS: &str = "alias";
|
||||
pub const MONEY_ALIASES_COL_TOKEN_ID: &str = "token_id";
|
||||
|
||||
pub const BALANCE_BASE10_DECIMALS: usize = 8;
|
||||
|
||||
impl Drk {
|
||||
/// Initialize wallet with tables for the Money contract.
|
||||
pub async fn initialize_money(&self) -> WalletDbResult<()> {
|
||||
// Initialize Money wallet schema
|
||||
let wallet_schema = include_str!("../../../src/contract/money/wallet.sql");
|
||||
let wallet_schema = include_str!("../money.sql");
|
||||
self.wallet.exec_batch_sql(wallet_schema).await?;
|
||||
|
||||
// Check if we have to initialize the Merkle tree.
|
||||
@@ -84,7 +127,7 @@ impl Drk {
|
||||
if self.last_scanned_slot().await.is_err() {
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}) VALUES (?1);",
|
||||
MONEY_INFO_TABLE, MONEY_INFO_COL_LAST_SCANNED_SLOT
|
||||
*MONEY_INFO_TABLE, MONEY_INFO_COL_LAST_SCANNED_SLOT
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![0]).await?;
|
||||
}
|
||||
@@ -102,7 +145,7 @@ impl Drk {
|
||||
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}) VALUES (?1, ?2, ?3);",
|
||||
MONEY_KEYS_TABLE,
|
||||
*MONEY_KEYS_TABLE,
|
||||
MONEY_KEYS_COL_IS_DEFAULT,
|
||||
MONEY_KEYS_COL_PUBLIC,
|
||||
MONEY_KEYS_COL_SECRET
|
||||
@@ -129,7 +172,7 @@ impl Drk {
|
||||
let row = match self
|
||||
.wallet
|
||||
.query_single(
|
||||
MONEY_KEYS_TABLE,
|
||||
&MONEY_KEYS_TABLE,
|
||||
&[MONEY_KEYS_COL_SECRET],
|
||||
convert_named_params! {(MONEY_KEYS_COL_IS_DEFAULT, 1)},
|
||||
)
|
||||
@@ -156,7 +199,7 @@ impl Drk {
|
||||
let row = match self
|
||||
.wallet
|
||||
.query_single(
|
||||
MONEY_KEYS_TABLE,
|
||||
&MONEY_KEYS_TABLE,
|
||||
&[MONEY_KEYS_COL_PUBLIC],
|
||||
convert_named_params! {(MONEY_KEYS_COL_IS_DEFAULT, 1)},
|
||||
)
|
||||
@@ -182,21 +225,21 @@ impl Drk {
|
||||
pub async fn set_default_address(&self, idx: usize) -> WalletDbResult<()> {
|
||||
// First we update previous default record
|
||||
let is_default = 0;
|
||||
let query = format!("UPDATE {} SET {} = ?1", MONEY_KEYS_TABLE, MONEY_KEYS_COL_IS_DEFAULT,);
|
||||
let query = format!("UPDATE {} SET {} = ?1", *MONEY_KEYS_TABLE, MONEY_KEYS_COL_IS_DEFAULT,);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![is_default]).await?;
|
||||
|
||||
// and then we set the new one
|
||||
let is_default = 1;
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1 WHERE {} = ?2",
|
||||
MONEY_KEYS_TABLE, MONEY_KEYS_COL_IS_DEFAULT, MONEY_KEYS_COL_KEY_ID,
|
||||
*MONEY_KEYS_TABLE, MONEY_KEYS_COL_IS_DEFAULT, MONEY_KEYS_COL_KEY_ID,
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![is_default, idx]).await
|
||||
}
|
||||
|
||||
/// Fetch all pukeys from the wallet.
|
||||
pub async fn addresses(&self) -> Result<Vec<(u64, PublicKey, SecretKey, u64)>> {
|
||||
let rows = match self.wallet.query_multiple(MONEY_KEYS_TABLE, &[], &[]).await {
|
||||
let rows = match self.wallet.query_multiple(&MONEY_KEYS_TABLE, &[], &[]).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
@@ -239,16 +282,18 @@ impl Drk {
|
||||
|
||||
/// Fetch all secret keys from the wallet.
|
||||
pub async fn get_money_secrets(&self) -> Result<Vec<SecretKey>> {
|
||||
let rows =
|
||||
match self.wallet.query_multiple(MONEY_KEYS_TABLE, &[MONEY_KEYS_COL_SECRET], &[]).await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
"[get_money_secrets] Secret keys retrieval failed: {e:?}"
|
||||
)))
|
||||
}
|
||||
};
|
||||
let rows = match self
|
||||
.wallet
|
||||
.query_multiple(&MONEY_KEYS_TABLE, &[MONEY_KEYS_COL_SECRET], &[])
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
"[get_money_secrets] Secret keys retrieval failed: {e:?}"
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
||||
let mut secrets = Vec::with_capacity(rows.len());
|
||||
|
||||
@@ -288,7 +333,7 @@ impl Drk {
|
||||
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}) VALUES (?1, ?2, ?3);",
|
||||
MONEY_KEYS_TABLE,
|
||||
*MONEY_KEYS_TABLE,
|
||||
MONEY_KEYS_COL_IS_DEFAULT,
|
||||
MONEY_KEYS_COL_PUBLIC,
|
||||
MONEY_KEYS_COL_SECRET
|
||||
@@ -331,11 +376,11 @@ impl Drk {
|
||||
/// The boolean in the returned tuple notes if the coin was marked as spent.
|
||||
pub async fn get_coins(&self, fetch_spent: bool) -> Result<Vec<(OwnCoin, bool)>> {
|
||||
let query = if fetch_spent {
|
||||
self.wallet.query_multiple(MONEY_COINS_TABLE, &[], &[]).await
|
||||
self.wallet.query_multiple(&MONEY_COINS_TABLE, &[], &[]).await
|
||||
} else {
|
||||
self.wallet
|
||||
.query_multiple(
|
||||
MONEY_COINS_TABLE,
|
||||
&MONEY_COINS_TABLE,
|
||||
&[],
|
||||
convert_named_params! {(MONEY_COINS_COL_IS_SPENT, false)},
|
||||
)
|
||||
@@ -444,7 +489,7 @@ impl Drk {
|
||||
eprintln!("Generating alias {alias} for Token: {token_id}");
|
||||
let query = format!(
|
||||
"INSERT OR REPLACE INTO {} ({}, {}) VALUES (?1, ?2);",
|
||||
MONEY_ALIASES_TABLE, MONEY_ALIASES_COL_ALIAS, MONEY_ALIASES_COL_TOKEN_ID,
|
||||
*MONEY_ALIASES_TABLE, MONEY_ALIASES_COL_ALIAS, MONEY_ALIASES_COL_TOKEN_ID,
|
||||
);
|
||||
self.wallet
|
||||
.exec_sql(&query, rusqlite::params![serialize(&alias), serialize(&token_id)])
|
||||
@@ -458,7 +503,7 @@ impl Drk {
|
||||
alias_filter: Option<String>,
|
||||
token_id_filter: Option<TokenId>,
|
||||
) -> Result<HashMap<String, TokenId>> {
|
||||
let rows = match self.wallet.query_multiple(MONEY_ALIASES_TABLE, &[], &[]).await {
|
||||
let rows = match self.wallet.query_multiple(&MONEY_ALIASES_TABLE, &[], &[]).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
@@ -512,8 +557,10 @@ impl Drk {
|
||||
/// Remove provided alias record from the wallet database.
|
||||
pub async fn remove_alias(&self, alias: String) -> WalletDbResult<()> {
|
||||
eprintln!("Removing alias: {alias}");
|
||||
let query =
|
||||
format!("DELETE FROM {} WHERE {} = ?1;", MONEY_ALIASES_TABLE, MONEY_ALIASES_COL_ALIAS,);
|
||||
let query = format!(
|
||||
"DELETE FROM {} WHERE {} = ?1;",
|
||||
*MONEY_ALIASES_TABLE, MONEY_ALIASES_COL_ALIAS,
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![serialize(&alias)]).await
|
||||
}
|
||||
|
||||
@@ -522,7 +569,7 @@ impl Drk {
|
||||
let is_spend = 0;
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1 WHERE {} = ?2",
|
||||
MONEY_COINS_TABLE, MONEY_COINS_COL_IS_SPENT, MONEY_COINS_COL_COIN,
|
||||
*MONEY_COINS_TABLE, MONEY_COINS_COL_IS_SPENT, MONEY_COINS_COL_COIN,
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![is_spend, serialize(&coin.inner())]).await
|
||||
}
|
||||
@@ -530,19 +577,19 @@ impl Drk {
|
||||
/// Replace the Money Merkle tree in the wallet.
|
||||
pub async fn put_money_tree(&self, tree: &MerkleTree) -> WalletDbResult<()> {
|
||||
// First we remove old record
|
||||
let query = format!("DELETE FROM {};", MONEY_TREE_TABLE);
|
||||
let query = format!("DELETE FROM {};", *MONEY_TREE_TABLE);
|
||||
self.wallet.exec_sql(&query, &[]).await?;
|
||||
|
||||
// then we insert the new one
|
||||
let query =
|
||||
format!("INSERT INTO {} ({}) VALUES (?1);", MONEY_TREE_TABLE, MONEY_TREE_COL_TREE,);
|
||||
format!("INSERT INTO {} ({}) VALUES (?1);", *MONEY_TREE_TABLE, MONEY_TREE_COL_TREE,);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![serialize(tree)]).await
|
||||
}
|
||||
|
||||
/// Fetch the Money Merkle tree from the wallet.
|
||||
pub async fn get_money_tree(&self) -> Result<MerkleTree> {
|
||||
let row =
|
||||
match self.wallet.query_single(MONEY_TREE_TABLE, &[MONEY_TREE_COL_TREE], &[]).await {
|
||||
match self.wallet.query_single(&MONEY_TREE_TABLE, &[MONEY_TREE_COL_TREE], &[]).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
@@ -562,7 +609,7 @@ impl Drk {
|
||||
pub async fn last_scanned_slot(&self) -> WalletDbResult<u64> {
|
||||
let ret = self
|
||||
.wallet
|
||||
.query_single(MONEY_INFO_TABLE, &[MONEY_INFO_COL_LAST_SCANNED_SLOT], &[])
|
||||
.query_single(&MONEY_INFO_TABLE, &[MONEY_INFO_COL_LAST_SCANNED_SLOT], &[])
|
||||
.await?;
|
||||
let Value::Integer(slot) = ret[0] else {
|
||||
return Err(WalletDbError::ParseColumnValueError);
|
||||
@@ -677,7 +724,7 @@ impl Drk {
|
||||
// into the wallet
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13);",
|
||||
MONEY_COINS_TABLE,
|
||||
*MONEY_COINS_TABLE,
|
||||
MONEY_COINS_COL_COIN,
|
||||
MONEY_COINS_COL_IS_SPENT,
|
||||
MONEY_COINS_COL_SERIAL,
|
||||
@@ -722,7 +769,7 @@ impl Drk {
|
||||
for token_id in freezes {
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = 1 WHERE {} = ?1;",
|
||||
MONEY_TOKENS_TABLE, MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_TOKEN_ID,
|
||||
*MONEY_TOKENS_TABLE, MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_TOKEN_ID,
|
||||
);
|
||||
|
||||
if let Err(e) =
|
||||
@@ -745,7 +792,7 @@ impl Drk {
|
||||
pub async fn mark_spent_coin(&self, coin: &Coin) -> WalletDbResult<()> {
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1 WHERE {} = ?2;",
|
||||
MONEY_COINS_TABLE, MONEY_COINS_COL_IS_SPENT, MONEY_COINS_COL_COIN
|
||||
*MONEY_COINS_TABLE, MONEY_COINS_COL_IS_SPENT, MONEY_COINS_COL_COIN
|
||||
);
|
||||
let is_spent = 1;
|
||||
self.wallet.exec_sql(&query, rusqlite::params![is_spent, serialize(&coin.inner())]).await
|
||||
@@ -785,7 +832,7 @@ impl Drk {
|
||||
/// Reset the Money coins in the wallet
|
||||
pub async fn reset_money_coins(&self) -> WalletDbResult<()> {
|
||||
eprintln!("Resetting coins");
|
||||
let query = format!("DELETE FROM {};", MONEY_COINS_TABLE);
|
||||
let query = format!("DELETE FROM {};", *MONEY_COINS_TABLE);
|
||||
self.wallet.exec_sql(&query, &[]).await?;
|
||||
eprintln!("Successfully reset coins");
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ use darkfi::{
|
||||
util::encoding::base64,
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_money_contract::client::{MONEY_INFO_COL_LAST_SCANNED_SLOT, MONEY_INFO_TABLE};
|
||||
use darkfi_sdk::crypto::ContractId;
|
||||
use darkfi_serial::{deserialize, serialize};
|
||||
|
||||
use super::{
|
||||
use crate::{
|
||||
error::{WalletDbError, WalletDbResult},
|
||||
money::{MONEY_INFO_COL_LAST_SCANNED_SLOT, MONEY_INFO_TABLE},
|
||||
Drk,
|
||||
};
|
||||
|
||||
@@ -179,7 +179,7 @@ impl Drk {
|
||||
|
||||
// Write this slot into `last_scanned_slot`
|
||||
let query =
|
||||
format!("UPDATE {} SET {} = ?1;", MONEY_INFO_TABLE, MONEY_INFO_COL_LAST_SCANNED_SLOT);
|
||||
format!("UPDATE {} SET {} = ?1;", *MONEY_INFO_TABLE, MONEY_INFO_COL_LAST_SCANNED_SLOT);
|
||||
if let Err(e) = self.wallet.exec_sql(&query, rusqlite::params![block.header.height]).await {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
"[scan_block_money] Update last scanned slot failed: {e:?}"
|
||||
@@ -264,7 +264,7 @@ impl Drk {
|
||||
// This might be a bit intense, but we accept it for now.
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1;",
|
||||
MONEY_INFO_TABLE, MONEY_INFO_COL_LAST_SCANNED_SLOT
|
||||
*MONEY_INFO_TABLE, MONEY_INFO_COL_LAST_SCANNED_SLOT
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![sl]).await?;
|
||||
}
|
||||
|
||||
@@ -27,11 +27,7 @@ use darkfi::{
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_money_contract::{
|
||||
client::{
|
||||
token_freeze_v1::TokenFreezeCallBuilder, token_mint_v1::TokenMintCallBuilder,
|
||||
MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_MINT_AUTHORITY, MONEY_TOKENS_COL_TOKEN_ID,
|
||||
MONEY_TOKENS_TABLE,
|
||||
},
|
||||
client::{token_freeze_v1::TokenFreezeCallBuilder, token_mint_v1::TokenMintCallBuilder},
|
||||
MoneyFunction, MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1, MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
@@ -41,7 +37,14 @@ use darkfi_sdk::{
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable};
|
||||
|
||||
use crate::{error::WalletDbResult, money::BALANCE_BASE10_DECIMALS, Drk};
|
||||
use crate::{
|
||||
error::WalletDbResult,
|
||||
money::{
|
||||
BALANCE_BASE10_DECIMALS, MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_MINT_AUTHORITY,
|
||||
MONEY_TOKENS_COL_TOKEN_ID, MONEY_TOKENS_TABLE,
|
||||
},
|
||||
Drk,
|
||||
};
|
||||
|
||||
impl Drk {
|
||||
/// Import a token mint authority into the wallet
|
||||
@@ -51,7 +54,7 @@ impl Drk {
|
||||
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}) VALUES (?1, ?2, ?3);",
|
||||
MONEY_TOKENS_TABLE,
|
||||
*MONEY_TOKENS_TABLE,
|
||||
MONEY_TOKENS_COL_MINT_AUTHORITY,
|
||||
MONEY_TOKENS_COL_TOKEN_ID,
|
||||
MONEY_TOKENS_COL_IS_FROZEN,
|
||||
@@ -66,7 +69,7 @@ impl Drk {
|
||||
}
|
||||
|
||||
pub async fn list_tokens(&self) -> Result<Vec<(TokenId, SecretKey, bool)>> {
|
||||
let rows = match self.wallet.query_multiple(MONEY_TOKENS_TABLE, &[], &[]).await {
|
||||
let rows = match self.wallet.query_multiple(&MONEY_TOKENS_TABLE, &[], &[]).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(Error::RusqliteError(format!(
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use rusqlite::types::Value;
|
||||
|
||||
use darkfi::{tx::Transaction, Error, Result};
|
||||
use darkfi_sdk::crypto::MONEY_CONTRACT_ID;
|
||||
use darkfi_serial::{deserialize, serialize};
|
||||
|
||||
use crate::{
|
||||
@@ -28,8 +30,11 @@ use crate::{
|
||||
};
|
||||
|
||||
// Wallet SQL table constant names. These have to represent the `wallet.sql`
|
||||
// SQL schema.
|
||||
const WALLET_TXS_HISTORY_TABLE: &str = "transactions_history";
|
||||
// SQL schema. Table names are prefixed with the contract ID to avoid collisions.
|
||||
lazy_static! {
|
||||
pub static ref WALLET_TXS_HISTORY_TABLE: String =
|
||||
format!("{}_transactions_history", MONEY_CONTRACT_ID.to_string());
|
||||
}
|
||||
const WALLET_TXS_HISTORY_COL_TX_HASH: &str = "transaction_hash";
|
||||
const WALLET_TXS_HISTORY_COL_STATUS: &str = "status";
|
||||
const WALLET_TXS_HISTORY_COL_TX: &str = "tx";
|
||||
@@ -39,7 +44,7 @@ impl Drk {
|
||||
pub async fn insert_tx_history_record(&self, tx: &Transaction) -> WalletDbResult<()> {
|
||||
let query = format!(
|
||||
"INSERT INTO {} ({}, {}, {}) VALUES (?1, ?2, ?3);",
|
||||
WALLET_TXS_HISTORY_TABLE,
|
||||
*WALLET_TXS_HISTORY_TABLE,
|
||||
WALLET_TXS_HISTORY_COL_TX_HASH,
|
||||
WALLET_TXS_HISTORY_COL_STATUS,
|
||||
WALLET_TXS_HISTORY_COL_TX,
|
||||
@@ -65,7 +70,7 @@ impl Drk {
|
||||
let row = match self
|
||||
.wallet
|
||||
.query_single(
|
||||
WALLET_TXS_HISTORY_TABLE,
|
||||
&WALLET_TXS_HISTORY_TABLE,
|
||||
&[],
|
||||
convert_named_params! {(WALLET_TXS_HISTORY_COL_TX_HASH, tx_hash)},
|
||||
)
|
||||
@@ -107,7 +112,7 @@ impl Drk {
|
||||
let rows = self
|
||||
.wallet
|
||||
.query_multiple(
|
||||
WALLET_TXS_HISTORY_TABLE,
|
||||
&WALLET_TXS_HISTORY_TABLE,
|
||||
&[WALLET_TXS_HISTORY_COL_TX_HASH, WALLET_TXS_HISTORY_COL_STATUS],
|
||||
&[],
|
||||
)
|
||||
@@ -139,7 +144,9 @@ impl Drk {
|
||||
) -> WalletDbResult<()> {
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1 WHERE {} = ?2;",
|
||||
WALLET_TXS_HISTORY_TABLE, WALLET_TXS_HISTORY_COL_STATUS, WALLET_TXS_HISTORY_COL_TX_HASH,
|
||||
*WALLET_TXS_HISTORY_TABLE,
|
||||
WALLET_TXS_HISTORY_COL_STATUS,
|
||||
WALLET_TXS_HISTORY_COL_TX_HASH,
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![status, tx_hash]).await
|
||||
}
|
||||
@@ -162,7 +169,7 @@ impl Drk {
|
||||
let txs_hashes_string = format!("{:?}", txs_hashes).replace('[', "(").replace(']', ")");
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1 WHERE {} IN {};",
|
||||
WALLET_TXS_HISTORY_TABLE,
|
||||
*WALLET_TXS_HISTORY_TABLE,
|
||||
WALLET_TXS_HISTORY_COL_STATUS,
|
||||
WALLET_TXS_HISTORY_COL_TX_HASH,
|
||||
txs_hashes_string
|
||||
@@ -175,7 +182,7 @@ impl Drk {
|
||||
pub async fn update_all_tx_history_records_status(&self, status: &str) -> WalletDbResult<()> {
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} = ?1",
|
||||
WALLET_TXS_HISTORY_TABLE, WALLET_TXS_HISTORY_COL_STATUS,
|
||||
*WALLET_TXS_HISTORY_TABLE, WALLET_TXS_HISTORY_COL_STATUS,
|
||||
);
|
||||
self.wallet.exec_sql(&query, rusqlite::params![status]).await
|
||||
}
|
||||
|
||||
@@ -39,49 +39,3 @@ pub use exec::DaoExecCall;
|
||||
|
||||
pub mod auth_xfer;
|
||||
pub use auth_xfer::DaoAuthMoneyTransferCall;
|
||||
|
||||
// Wallet SQL table constant names. These have to represent the SQL schema.
|
||||
pub const DAO_DAOS_TABLE: &str = "dao_daos";
|
||||
pub const DAO_DAOS_COL_DAO_ID: &str = "dao_id";
|
||||
pub const DAO_DAOS_COL_NAME: &str = "name";
|
||||
pub const DAO_DAOS_COL_PROPOSER_LIMIT: &str = "proposer_limit";
|
||||
pub const DAO_DAOS_COL_QUORUM: &str = "quorum";
|
||||
pub const DAO_DAOS_COL_APPROVAL_RATIO_BASE: &str = "approval_ratio_base";
|
||||
pub const DAO_DAOS_COL_APPROVAL_RATIO_QUOT: &str = "approval_ratio_quot";
|
||||
pub const DAO_DAOS_COL_GOV_TOKEN_ID: &str = "gov_token_id";
|
||||
pub const DAO_DAOS_COL_SECRET: &str = "secret";
|
||||
pub const DAO_DAOS_COL_BULLA_BLIND: &str = "bulla_blind";
|
||||
pub const DAO_DAOS_COL_LEAF_POSITION: &str = "leaf_position";
|
||||
pub const DAO_DAOS_COL_TX_HASH: &str = "tx_hash";
|
||||
pub const DAO_DAOS_COL_CALL_INDEX: &str = "call_index";
|
||||
|
||||
pub const DAO_TREES_TABLE: &str = "dao_trees";
|
||||
pub const DAO_TREES_COL_DAOS_TREE: &str = "daos_tree";
|
||||
pub const DAO_TREES_COL_PROPOSALS_TREE: &str = "proposals_tree";
|
||||
|
||||
pub const DAO_COINS_TABLE: &str = "dao_coins";
|
||||
pub const DAO_COINS_COL_COIN_ID: &str = "coin_id";
|
||||
pub const DAO_COINS_COL_DAO_ID: &str = "dao_id";
|
||||
|
||||
pub const DAO_PROPOSALS_TABLE: &str = "dao_proposals";
|
||||
pub const DAO_PROPOSALS_COL_PROPOSAL_ID: &str = "proposal_id";
|
||||
pub const DAO_PROPOSALS_COL_DAO_ID: &str = "dao_id";
|
||||
pub const DAO_PROPOSALS_COL_RECV_PUBLIC: &str = "recv_public";
|
||||
pub const DAO_PROPOSALS_COL_AMOUNT: &str = "amount";
|
||||
pub const DAO_PROPOSALS_COL_SENDCOIN_TOKEN_ID: &str = "sendcoin_token_id";
|
||||
pub const DAO_PROPOSALS_COL_BULLA_BLIND: &str = "bulla_blind";
|
||||
pub const DAO_PROPOSALS_COL_LEAF_POSITION: &str = "leaf_position";
|
||||
pub const DAO_PROPOSALS_COL_MONEY_SNAPSHOT_TREE: &str = "money_snapshot_tree";
|
||||
pub const DAO_PROPOSALS_COL_TX_HASH: &str = "tx_hash";
|
||||
pub const DAO_PROPOSALS_COL_CALL_INDEX: &str = "call_index";
|
||||
pub const DAO_PROPOSALS_COL_OUR_VOTE_ID: &str = "our_vote_id";
|
||||
|
||||
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";
|
||||
|
||||
@@ -56,45 +56,6 @@ pub mod token_freeze_v1;
|
||||
/// `Money::PoWRewardV1` API
|
||||
pub mod pow_reward_v1;
|
||||
|
||||
// Wallet SQL table constant names. These have to represent the `wallet.sql`
|
||||
// SQL schema.
|
||||
// TODO: They should also be prefixed with the contract ID to avoid collisions.
|
||||
pub const MONEY_INFO_TABLE: &str = "money_info";
|
||||
pub const MONEY_INFO_COL_LAST_SCANNED_SLOT: &str = "last_scanned_slot";
|
||||
|
||||
pub const MONEY_TREE_TABLE: &str = "money_tree";
|
||||
pub const MONEY_TREE_COL_TREE: &str = "tree";
|
||||
|
||||
pub const MONEY_KEYS_TABLE: &str = "money_keys";
|
||||
pub const MONEY_KEYS_COL_KEY_ID: &str = "key_id";
|
||||
pub const MONEY_KEYS_COL_IS_DEFAULT: &str = "is_default";
|
||||
pub const MONEY_KEYS_COL_PUBLIC: &str = "public";
|
||||
pub const MONEY_KEYS_COL_SECRET: &str = "secret";
|
||||
|
||||
pub const MONEY_COINS_TABLE: &str = "money_coins";
|
||||
pub const MONEY_COINS_COL_COIN: &str = "coin";
|
||||
pub const MONEY_COINS_COL_IS_SPENT: &str = "is_spent";
|
||||
pub const MONEY_COINS_COL_SERIAL: &str = "serial";
|
||||
pub const MONEY_COINS_COL_VALUE: &str = "value";
|
||||
pub const MONEY_COINS_COL_TOKEN_ID: &str = "token_id";
|
||||
pub const MONEY_COINS_COL_SPEND_HOOK: &str = "spend_hook";
|
||||
pub const MONEY_COINS_COL_USER_DATA: &str = "user_data";
|
||||
pub const MONEY_COINS_COL_VALUE_BLIND: &str = "value_blind";
|
||||
pub const MONEY_COINS_COL_TOKEN_BLIND: &str = "token_blind";
|
||||
pub const MONEY_COINS_COL_SECRET: &str = "secret";
|
||||
pub const MONEY_COINS_COL_NULLIFIER: &str = "nullifier";
|
||||
pub const MONEY_COINS_COL_LEAF_POSITION: &str = "leaf_position";
|
||||
pub const MONEY_COINS_COL_MEMO: &str = "memo";
|
||||
|
||||
pub const MONEY_TOKENS_TABLE: &str = "money_tokens";
|
||||
pub const MONEY_TOKENS_COL_MINT_AUTHORITY: &str = "mint_authority";
|
||||
pub const MONEY_TOKENS_COL_TOKEN_ID: &str = "token_id";
|
||||
pub const MONEY_TOKENS_COL_IS_FROZEN: &str = "is_frozen";
|
||||
|
||||
pub const MONEY_ALIASES_TABLE: &str = "money_aliases";
|
||||
pub const MONEY_ALIASES_COL_ALIAS: &str = "alias";
|
||||
pub const MONEY_ALIASES_COL_TOKEN_ID: &str = "token_id";
|
||||
|
||||
/// `MoneyNote` holds the inner attributes of a `Coin`
|
||||
/// It does not store the public key since it's encrypted for that key,
|
||||
/// and so is not needed to infer the coin attributes.
|
||||
|
||||
Reference in New Issue
Block a user