Просмотр исходного кода

Merge branch 'master' of github.com:darkrenaissance/darkfi

narodnik 4 лет назад
Родитель
Сommit
0561ed1b42
96 измененных файлов с 1119 добавлено и 2560 удалено
  1. 47 655
      Cargo.lock
  2. 39 49
      Cargo.toml
  3. 3 0
      bin/cashier/.gitignore
  4. 61 0
      bin/cashier/Cargo.toml
  5. 12 14
      bin/cashier/example/eth.rs
  6. 1 0
      bin/cashier/src/lib.rs
  7. 83 199
      bin/cashier/src/main.rs
  8. 3 3
      bin/cashier/src/service/bridge.rs
  9. 50 16
      bin/cashier/src/service/btc.rs
  10. 55 16
      bin/cashier/src/service/eth.rs
  11. 0 4
      bin/cashier/src/service/mod.rs
  12. 45 8
      bin/cashier/src/service/sol.rs
  13. 3 0
      bin/darkfid/.gitignore
  14. 36 0
      bin/darkfid/Cargo.toml
  15. 24 24
      bin/darkfid/src/main.rs
  16. 3 0
      bin/drk/.gitignore
  17. 26 0
      bin/drk/Cargo.toml
  18. 7 3
      bin/drk/src/main.rs
  19. 3 0
      bin/gateway/.gitignore
  20. 29 0
      bin/gateway/Cargo.toml
  21. 4 4
      bin/gateway/src/main.rs
  22. 8 13
      bin/ircd/src/irc_server.rs
  23. 33 26
      bin/ircd/src/main.rs
  24. 4 8
      bin/ircd/src/privmsg.rs
  25. 2 14
      bin/ircd/src/program_options.rs
  26. 4 10
      bin/ircd/src/protocol_privmsg.rs
  27. 1 1
      bin/map/Cargo.toml
  28. 89 0
      bin/map/src/app.rs
  29. 44 0
      bin/map/src/list.rs
  30. 41 36
      bin/map/src/main.rs
  31. 7 0
      bin/map/src/mod.rs
  32. 31 0
      bin/map/src/ui.rs
  33. 1 0
      book/src/SUMMARY.md
  34. 102 79
      book/src/zkas/examples/sapling.md
  35. 50 0
      book/src/zkas/examples/voting.md
  36. 1 1
      contrib/zk.lua
  37. 1 1
      example/net.rs
  38. 1 1
      example/tree.rs
  39. 1 1
      example/tui_ex.rs
  40. 3 3
      example/tx.rs
  41. 3 3
      example/vm.rs
  42. 3 3
      example/vm_burn.rs
  43. 1 1
      script/run_burn_zk.sh
  44. 1 1
      script/run_mint_zk.sh
  45. 0 151
      src/bin/darkpulse.rs
  46. 0 0
      src/chain/mod.rs
  47. 1 1
      src/chain/rocks.rs
  48. 1 1
      src/chain/slab.rs
  49. 1 1
      src/chain/slabstore.rs
  50. 0 11
      src/cli/cli_config.rs
  51. 1 0
      src/cli/mod.rs
  52. 1 1
      src/crypto/mint_proof.rs
  53. 1 1
      src/crypto/spend_proof.rs
  54. 0 53
      src/darkpulse/aes.rs
  55. 0 89
      src/darkpulse/channel.rs
  56. 0 176
      src/darkpulse/cli_option.rs
  57. 0 64
      src/darkpulse/control_message.rs
  58. 0 156
      src/darkpulse/dbsql.rs
  59. 0 21
      src/darkpulse/mod.rs
  60. 0 104
      src/darkpulse/net/messages.rs
  61. 0 2
      src/darkpulse/net/mod.rs
  62. 0 175
      src/darkpulse/net/protocol_slab.rs
  63. 0 1
      src/darkpulse/net/protocols/mod.rs
  64. 0 119
      src/darkpulse/slabs_manager.rs
  65. 0 164
      src/darkpulse/utility.rs
  66. 16 18
      src/lib.rs
  67. 12 9
      src/node/client.rs
  68. 4 0
      src/node/mod.rs
  69. 1 1
      src/node/service/gateway.rs
  70. 4 0
      src/node/service/mod.rs
  71. 0 0
      src/node/service/reqrep.rs
  72. 3 2
      src/node/state.rs
  73. 8 7
      src/node/wallet/cashierdb.rs
  74. 0 0
      src/node/wallet/mod.rs
  75. 0 0
      src/node/wallet/wallet_api.rs
  76. 9 8
      src/node/wallet/walletdb.rs
  77. 1 1
      src/tx/mod.rs
  78. 1 1
      src/util/async_serial.rs
  79. 0 0
      src/util/endian.rs
  80. 9 12
      src/util/error.rs
  81. 3 3
      src/util/loader.rs
  82. 8 1
      src/util/mod.rs
  83. 2 4
      src/util/parse.rs
  84. 17 2
      src/util/path.rs
  85. 0 0
      src/util/rpc/jsonrpc.rs
  86. 0 0
      src/util/rpc/mod.rs
  87. 1 1
      src/util/rpc/rpcserver.rs
  88. 0 0
      src/util/rpc/websockets.rs
  89. 1 1
      src/util/serial.rs
  90. 0 0
      src/zk/circuit/mint_contract.rs
  91. 0 0
      src/zk/circuit/mod.rs
  92. 0 0
      src/zk/circuit/spend_contract.rs
  93. 3 0
      src/zk/mod.rs
  94. 0 0
      src/zk/vm.rs
  95. 1 1
      src/zk/vm_serial.rs
  96. 43 0
      zkas/proofs/voting.zk

Разница между файлами не показана из-за своего большого размера
+ 47 - 655
Cargo.lock


+ 39 - 49
Cargo.toml

@@ -9,19 +9,21 @@ license = "AGPL-3.0-only"
 edition = "2021"
 
 [lib]
-name = "drk"
+name = "darkfi"
 
 [dependencies.halo2_gadgets]
 git = "https://github.com/parazyd/halo2_gadgets.git"
 rev = "b45c527276bb2309f3b256eb5f45ccdcc5bd8c0f"
 features = ["dev-graph", "test-dependencies"]
 
+# blockchain dependencies
 [dependencies.rocksdb]
 # TODO: Revert to upstream after bd966750ec861d687913d59a9939a1408ac53131 is merged.
 git = "https://github.com/parazyd/rust-rocksdb"
 rev = "bd966750ec861d687913d59a9939a1408ac53131"
 default-features = false
 features = ["zstd"]
+optional = true
 
 [dependencies]
 # Crypto
@@ -35,7 +37,6 @@ group = "0.11.0"
 crypto_api_chachapoly = "0.5.0"
 arrayvec = "0.7.2"
 sha2 = "0.9.8"
-ripemd160 = "0.9.1"
 
 # Encoding and parsing
 bincode = "1.3.3"
@@ -51,7 +52,6 @@ serde = {version = "1.0.130", features = ["derive"]}
 async-std = "1.10.0"
 async-trait = "0.1.51"
 async-channel = "1.6.1"
-easy-parallel = "3.1.0"
 native-tls = "0.2.8"
 async-native-tls = "0.4.0"
 async-executor = "1.4.1"
@@ -66,66 +66,56 @@ failure = "0.1.8"
 lazy_static = "1.4.0"
 log = "0.4.14"
 num_cpus = "1.13.0"
-simplelog = "0.11.1"
 signal-hook = "0.3.10"
-signal-hook-async-std = "0.2.1"
+simplelog = "0.11.1"
 subtle = "2.4.1"
 thiserror = "1.0.30"
-prettytable-rs = "0.8.0"
 
 # Used for Websockets client implementation.
 async-tungstenite = "0.16.0"
 tungstenite = "0.16.0"
 
-# Used for wallet management.
-sqlx = {version = "0.5.10", features = ["runtime-async-std-native-tls", "sqlite"]}
-libsqlite3-sys = {version = "0.23.1", features = ["bundled-sqlcipher"]}
-
-# Used for gatewayd network transport.
-zeromq = {version = "0.3.1", default-features = false, features = ["async-std-runtime", "all-transport"]}
-
-# Cashier Bitcoin dependencies
-bdk = {version = "0.14.0", optional = true}
-bitcoin = {version = "0.27.1", optional = true}
-secp256k1 = {version = "0.20.3", default-features = false, features = ["rand-std"], optional = true}
-
-# Cashier Ethereum dependencies
-hash-db = {version = "0.15.2", optional = true}
-keccak-hasher = {version = "0.15.3", optional = true}
-
-# Cashier Solana dependencies
-solana-client = {version = "1.8.11", optional = true}
-solana-sdk = {version = "1.8.11", optional = true}
-spl-associated-token-account = {version = "1.0.3", features = ["no-entrypoint"], optional = true}
-spl-token = {version = "3.2.0", features = ["no-entrypoint"], optional = true}
-
-# Darkpulse and tui dependencies
-aes-gcm = {version = "0.9.4", optional = true}
-chrono = {version = "0.4.19", optional = true}
-rusqlite = {version = "0.26.3", optional = true}
+#tui dependencies
 crossbeam-channel = { version = "0.5.1", optional = true}
 libc = { version = "0.2.112", optional = true}
 termion = { version = "1.5.6", optional = true}
 
+# node dependencies
+## Used for wallet management.
+sqlx = {version = "0.5.10", features = ["runtime-async-std-native-tls", "sqlite"], optional = true}
+libsqlite3-sys = {version = "0.23.1", features = ["bundled-sqlcipher"],  optional = true }
+## Used for gatewayd network transport.
+zeromq = {version = "0.3.1", default-features = false, features = ["async-std-runtime", "all-transport"],  optional = true }
+signal-hook-async-std = {version = "0.2.1", optional = true}
+
 [features]
-btc = ["bdk", "bitcoin", "secp256k1"]
-eth = ["keccak-hasher", "hash-db"]
-sol = ["solana-sdk", "solana-client", "spl-token", "spl-associated-token-account"]
-darkpulse = ["aes-gcm", "chrono","rusqlite"]
-tui = ["termion", "chrono","libc", "crossbeam-channel"]
-
-[[bin]]         
-name = "darkpulse"    
-required-features = ["darkpulse"]
-
-[[bin]]         
-name = "eth"    
-required-features = ["eth"]
-
-[[bin]]         
-name = "tui_ex"    
-required-features = ["tui"]
+chain = ["rocksdb"]
+node = ["sqlx", "libsqlite3-sys", "zeromq", "signal-hook-async-std"]
+tui = ["termion", "libc", "crossbeam-channel"]
 
 [[example]]
 name = "net"
 path = "example/net.rs"
+required-features = ["node", "chain"]
+
+[[example]]
+name = "tui"
+path = "example/tui_ex.rs"
+required-features = ["tui"]
+
+[[example]]
+name = "vm"
+path = "example/vm.rs"
+
+[[example]]
+name = "vm_burn"
+path = "example/vm_burn.rs"
+
+[[example]]
+name = "tx"
+path = "example/tx.rs"
+required-features = ["node"]
+
+[[example]]
+name = "tree"
+path = "example/tree.rs"

+ 3 - 0
bin/cashier/.gitignore

@@ -0,0 +1,3 @@
+
+/target
+Cargo.lock

+ 61 - 0
bin/cashier/Cargo.toml

@@ -0,0 +1,61 @@
+[package]
+name = "cashier"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+darkfi = {path= "../../", features = ["node", "chain"]}
+
+# Encoding and parsing
+serde_json = "1.0.72"
+serde = {version = "1.0.130", features = ["derive"]}
+hex = "0.4.3"
+url = "2.2.2"
+
+# Utilities
+clap = { version = "3.0.0", features = ["derive"] }
+log = "0.4.14"
+simplelog = "0.11.1"
+thiserror = "1.0.30"
+rand = "0.8.4"
+num_cpus = "1.13.0"
+lazy_static = "1.4.0"
+anyhow = "1.0.49"
+num-bigint = {version = "0.4.3", features = ["rand", "serde"]}
+
+# Used for Websockets client implementation.
+async-tungstenite = "0.16.0"
+tungstenite = "0.16.0"
+
+# Async
+async-std = "1.10.0"
+async-trait = "0.1.51"
+async-channel = "1.6.1"
+easy-parallel = "3.1.0"
+async-executor = "1.4.1"
+futures = "0.3.17"
+smol = "1.2.5"
+native-tls = "0.2.8"
+async-native-tls = "0.4.0"
+
+# Cashier Bitcoin dependencies
+bdk = {version = "0.14.0", optional = true}
+bitcoin = {version = "0.27.1", optional = true}
+secp256k1 = {version = "0.20.3", default-features = false, features = ["rand-std"], optional = true}
+
+# Cashier Ethereum dependencies
+hash-db = {version = "0.15.2", optional = true}
+keccak-hasher = {version = "0.15.3", optional = true}
+
+# Cashier Solana dependencies
+solana-client = {version = "1.8.11", optional = true}
+solana-sdk = {version = "1.8.11", optional = true}
+spl-associated-token-account = {version = "1.0.3", features = ["no-entrypoint"], optional = true}
+spl-token = {version = "3.2.0", features = ["no-entrypoint"], optional = true}
+
+[features]
+btc = ["bdk", "bitcoin", "secp256k1"]
+eth = ["keccak-hasher", "hash-db"]
+sol = ["solana-sdk", "solana-client", "spl-token", "spl-associated-token-account"]

+ 12 - 14
src/bin/eth.rs → bin/cashier/example/eth.rs

@@ -1,8 +1,8 @@
 use num_bigint::BigUint;
 use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 
-use drk::{
-    service::eth::{erc20_transfer_data, EthClient, EthTx, Keypair},
+use darkfi::{
+    service::eth::{erc20_transfer_data, EthClient, EthTx},
     util::{decode_base10, encode_base10},
     Result,
 };
@@ -19,12 +19,10 @@ async fn main() -> Result<()> {
     let acc = "0x113b6648f34f4d0340d04ff171cbcf0b49d47827".to_string();
     let key = "67cbb73cb293eea5fa2a7025d5479dbd50319010c03fd8821917ad0d9d53276c".to_string();
 
-    let mut eth = EthClient::new(
-        "/home/parazyd/.ethereum/ropsten/geth.ipc".to_string(),
-        String::from("foobar"),
-    );
+    let mut eth = EthClient::new("", "/home/parazyd/.ethereum/ropsten/geth.ipc", "foobar");
 
-    eth.set_main_keypair(&Keypair { private_key: key, public_key: acc.clone() });
+    eth.main_keypair.private_key = key;
+    eth.main_keypair.public_key = acc.clone();
 
     //let key = generate_privkey();
     //let passphrase = "foobar".to_string();
@@ -49,13 +47,13 @@ async fn main() -> Result<()> {
     /*
     // Transfer native ETH
     let tx = EthTx::new(
-        &acc,
-        &dest,
-        None,
-        None,
-        Some(decode_base10("0.051", 18, true)?),
-        None,
-        None,
+    &acc,
+    &dest,
+    None,
+    None,
+    Some(decode_base10("0.051", 18, true)?),
+    None,
+    None,
     );
 
     let rep = eth.send_transaction(&tx, &passphrase).await?;

+ 1 - 0
bin/cashier/src/lib.rs

@@ -0,0 +1 @@
+pub mod service;

+ 83 - 199
src/bin/cashierd.rs → bin/cashier/src/main.rs

@@ -10,31 +10,37 @@ use rand::rngs::OsRng;
 use serde_json::{json, Value};
 use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 
-use drk::{
-    blockchain::{rocks::columns, Rocks, RocksColumn},
-    circuit::{MintContract, SpendContract},
+use darkfi::{
+    chain::{rocks::columns, Rocks, RocksColumn},
     cli::{CashierdConfig, CliCashierd, Config},
-    client::Client,
     crypto::{
         keypair::{PublicKey, SecretKey},
         proof::VerifyingKey,
     },
-    rpc::{
-        jsonrpc::{error as jsonerr, response as jsonresp, ErrorCode::*, JsonRequest, JsonResult},
-        rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
+    node::{
+        client::Client,
+        state::State,
+        wallet::{cashierdb::CashierDb, walletdb::WalletDb},
     },
-    serial::{deserialize, serialize},
-    service::{bridge, bridge::Bridge},
-    state::State,
+    serial::serialize,
     types::DrkTokenId,
-    util::{expand_path, generate_id2, join_config_path, parse::truncate, Address, NetworkName},
-    wallet::{
-        cashierdb::{CashierDb, TokenKey},
-        walletdb::WalletDb,
+    util::{
+        expand_path, generate_id2, join_config_path,
+        parse::truncate,
+        rpc::{
+            jsonrpc::{
+                error as jsonerr, response as jsonresp, ErrorCode::*, JsonRequest, JsonResult,
+            },
+            rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
+        },
+        Address, NetworkName,
     },
+    zk::circuit::{MintContract, SpendContract},
     Error, Result,
 };
 
+use cashier::service::{bridge, bridge::Bridge};
+
 fn handle_bridge_error(error_code: u32) -> Result<()> {
     match error_code {
         1 => Err(Error::BridgeError("Not Supported Client".into())),
@@ -55,7 +61,7 @@ struct Cashierd {
     bridge: Arc<Bridge>,
     cashier_wallet: Arc<CashierDb>,
     networks: Vec<Network>,
-    public_key: String,
+    public_key: Address,
     config: CashierdConfig,
 }
 
@@ -81,18 +87,17 @@ impl RequestHandler for Cashierd {
 }
 
 impl Cashierd {
-    async fn new(config: CashierdConfig) -> Result<Self> {
+    async fn new(config: CashierdConfig, public_key: Address) -> Result<Self> {
         debug!(target: "CASHIER DAEMON", "Initialize");
 
         let wallet_path =
             format!("sqlite://{}", expand_path(&config.cashier_wallet_path)?.to_str().unwrap());
-        let cashier_wallet =
-            CashierDb::new(&wallet_path, config.cashier_wallet_password.clone()).await?;
+
+        let cashier_wallet = CashierDb::new(&wallet_path, &config.cashier_wallet_password).await?;
 
         let mut networks = Vec::new();
 
-        let cfg = config.clone();
-        for network in cfg.networks {
+        for network in config.clone().networks {
             networks.push(Network {
                 name: NetworkName::from_str(&network.name)?,
                 blockchain: network.blockchain,
@@ -102,7 +107,7 @@ impl Cashierd {
 
         let bridge = bridge::Bridge::new();
 
-        Ok(Self { bridge, cashier_wallet, networks, public_key: String::from(""), config })
+        Ok(Self { bridge, cashier_wallet, networks, public_key, config })
     }
 
     async fn start(
@@ -118,143 +123,56 @@ impl Cashierd {
                 #[cfg(feature = "sol")]
                 NetworkName::Solana => {
                     debug!(target: "CASHIER DAEMON", "Adding solana network");
-                    use drk::service::{sol::SolFailed, SolClient};
-                    use solana_sdk::{signature::Signer, signer::keypair::Keypair};
-
-                    let bridge2 = self.bridge.clone();
-
-                    let main_keypair: Keypair;
-
-                    let main_keypairs =
-                        self.cashier_wallet.get_main_keys(&NetworkName::Solana).await?;
-
-                    if network.keypair.is_empty() {
-                        if main_keypairs.is_empty() {
-                            main_keypair = Keypair::new();
-                            self.cashier_wallet
-                                .put_main_keys(
-                                    &TokenKey {
-                                        secret_key: serialize(&main_keypair),
-                                        public_key: serialize(&main_keypair.pubkey()),
-                                    },
-                                    &NetworkName::Solana,
-                                )
-                                .await?;
-                        } else {
-                            main_keypair =
-                                deserialize(&main_keypairs[main_keypairs.len() - 1].secret_key)?;
-                        }
-                    } else {
-                        let keypair_str = drk::cli::cli_config::load_keypair_to_str(expand_path(
-                            &network.keypair.clone(),
-                        )?)?;
-                        let keypair_bytes: Vec<u8> = serde_json::from_str(&keypair_str)?;
-                        main_keypair = Keypair::from_bytes(&keypair_bytes)
-                            .map_err(|e| SolFailed::Signature(e.to_string()))?;
-                    }
+                    use drk::service::SolClient;
+
+                    let _bridge = self.bridge.clone();
 
-                    let sol_client = SolClient::new(main_keypair, &network.blockchain).await?;
+                    let sol_client = SolClient::new(
+                        self.cashier_wallet.clone(),
+                        &network.blockchain,
+                        &network.keypair,
+                    )
+                    .await?;
 
-                    bridge2.add_clients(NetworkName::Solana, sol_client).await?;
+                    _bridge.add_clients(NetworkName::Solana, sol_client).await?;
                 }
 
                 #[cfg(feature = "eth")]
                 NetworkName::Ethereum => {
                     debug!(target: "CASHIER DAEMON", "Adding ethereum network");
-                    use drk::service::{
-                        eth::{generate_privkey, Keypair},
-                        EthClient,
-                    };
 
-                    let bridge2 = self.bridge.clone();
+                    use drk::service::EthClient;
 
-                    let main_keypair: Keypair;
-
-                    let main_keypairs =
-                        self.cashier_wallet.get_main_keys(&NetworkName::Ethereum).await?;
+                    let _bridge = self.bridge.clone();
 
                     let passphrase = self.config.geth_passphrase.clone();
 
                     let mut eth_client = EthClient::new(
-                        expand_path(&self.config.geth_socket)?.to_str().unwrap().into(),
-                        passphrase.clone(),
+                        &network.blockchain,
+                        expand_path(&self.config.geth_socket)?.to_str().unwrap(),
+                        &passphrase,
                     );
 
-                    if main_keypairs.is_empty() {
-                        let main_private_key = generate_privkey();
-                        let main_public_key = eth_client
-                            .import_privkey(&main_private_key, &passphrase)
-                            .await?
-                            .as_str()
-                            .unwrap()
-                            .to_string();
-
-                        self.cashier_wallet
-                            .put_main_keys(
-                                &TokenKey {
-                                    secret_key: serialize(&main_private_key),
-                                    public_key: serialize(&main_public_key),
-                                },
-                                &NetworkName::Ethereum,
-                            )
-                            .await?;
-
-                        main_keypair =
-                            Keypair { private_key: main_private_key, public_key: main_public_key };
-                    } else {
-                        let last_keypair = &main_keypairs[main_keypairs.len() - 1];
-
-                        main_keypair = Keypair {
-                            private_key: deserialize(&last_keypair.secret_key)?,
-                            public_key: deserialize(&last_keypair.public_key)?,
-                        }
-                    }
+                    eth_client.setup_keypair(self.cashier_wallet.clone(), &network.keypair).await?;
 
-                    eth_client.set_main_keypair(&main_keypair);
-
-                    bridge2.add_clients(NetworkName::Ethereum, Arc::new(eth_client)).await?;
+                    _bridge.add_clients(NetworkName::Ethereum, Arc::new(eth_client)).await?;
                 }
 
                 #[cfg(feature = "btc")]
                 NetworkName::Bitcoin => {
                     debug!(target: "CASHIER DAEMON", "Adding bitcoin network");
-                    use drk::service::btc::{BtcClient, BtcFailed, Keypair};
-
-                    let bridge2 = self.bridge.clone();
-
-                    let main_keypair: Keypair;
-
-                    let main_keypairs =
-                        self.cashier_wallet.get_main_keys(&NetworkName::Bitcoin).await?;
-
-                    if network.keypair.is_empty() {
-                        if main_keypairs.is_empty() {
-                            main_keypair = Keypair::new();
-                            self.cashier_wallet
-                                .put_main_keys(
-                                    &TokenKey {
-                                        secret_key: serialize(&main_keypair),
-                                        public_key: serialize(&main_keypair.pubkey()),
-                                    },
-                                    &NetworkName::Bitcoin,
-                                )
-                                .await?;
-                        } else {
-                            main_keypair =
-                                deserialize(&main_keypairs[main_keypairs.len() - 1].secret_key)?;
-                        }
-                    } else {
-                        let keypair_str = drk::cli::cli_config::load_keypair_to_str(expand_path(
-                            &network.keypair.clone(),
-                        )?)?;
-                        let keypair_bytes: Vec<u8> = serde_json::from_str(&keypair_str)?;
-                        main_keypair = Keypair::from_bytes(&keypair_bytes)
-                            .map_err(|e| BtcFailed::DecodeAndEncodeError(e.to_string()))?;
-                    }
+                    use drk::service::btc::BtcClient;
 
-                    let btc_client = BtcClient::new(main_keypair, &network.blockchain).await?;
+                    let _bridge = self.bridge.clone();
 
-                    bridge2.add_clients(NetworkName::Bitcoin, btc_client).await?;
+                    let btc_client = BtcClient::new(
+                        self.cashier_wallet.clone(),
+                        &network.blockchain,
+                        &network.keypair,
+                    )
+                    .await?;
+
+                    _bridge.add_clients(NetworkName::Bitcoin, btc_client).await?;
                 }
                 _ => {}
             }
@@ -640,7 +558,7 @@ impl Cashierd {
         {
             "server_version": env!("CARGO_PKG_VERSION"),
             "protocol_version": "1.0",
-            "public_key": self.public_key,
+            "public_key": self.public_key.to_string(),
             "networks": [],
             "hosts": {
                 "tcp_port": tcp_port,
@@ -669,12 +587,10 @@ async fn start(
     config: &CashierdConfig,
     get_address_flag: bool,
 ) -> Result<()> {
-    let mut cashierd = Cashierd::new(config.clone()).await?;
-
     let client_wallet_path =
         format!("sqlite://{}", expand_path(&config.client_wallet_path)?.to_str().unwrap());
-    let client_wallet =
-        WalletDb::new(&client_wallet_path, config.client_wallet_password.clone()).await?;
+
+    let client_wallet = WalletDb::new(&client_wallet_path, &config.client_wallet_password).await?;
 
     let rocks = Rocks::new(expand_path(&config.database_path.clone())?.as_path())?;
 
@@ -683,37 +599,42 @@ async fn start(
     info!("Building verifying key for the spend contract...");
     let spend_vk = VerifyingKey::build(11, SpendContract::default());
 
-    let client = Client::new(
-        rocks.clone(),
-        (config.gateway_protocol_url.parse()?, config.gateway_publisher_url.parse()?),
-        client_wallet.clone(),
-    )
-    .await?;
+    // new Client
+    let gateway_urls =
+        (config.gateway_protocol_url.parse()?, config.gateway_publisher_url.parse()?);
+    let client = Client::new(rocks.clone(), gateway_urls, client_wallet.clone()).await?;
 
     let tree = client.get_tree().await?;
     let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
     let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
 
+    // get cashier public key
     let cashier_public = client.main_keypair.public;
-    let cashier_public_str = Address::from(cashier_public).to_string();
-    cashierd.public_key = cashier_public_str.clone();
 
-    let cashier_public_keys = vec![cashier_public];
+    // new Cashier daemon
+    let mut cashierd = Cashierd::new(config.clone(), Address::from(cashier_public)).await?;
 
+    // this will print the cashier public key and exit
+    if get_address_flag {
+        info!("Public Key: {}", cashierd.public_key);
+        return Ok(())
+    };
+
+    // new State
+    let public_keys = vec![cashier_public];
     let state = Arc::new(Mutex::new(State {
         tree,
         merkle_roots,
         nullifiers,
-        public_keys: cashier_public_keys,
+        public_keys,
         mint_vk,
         spend_vk,
     }));
 
-    if get_address_flag {
-        info!("Public Key: {}", cashier_public_str);
-        return Ok(())
-    };
+    // start cashier
+    let (t1, t2) = cashierd.start(client, state, executor.clone()).await?;
 
+    // config for rpc
     let cfg = RpcServerConfig {
         socket_addr: config.rpc_listen_address,
         use_tls: config.serve_tls,
@@ -721,7 +642,7 @@ async fn start(
         identity_pass: config.tls_identity_password.clone(),
     };
 
-    let (t1, t2) = cashierd.start(client, state, executor.clone()).await?;
+    // listen and serve RPC
     listen_and_serve(cfg, Arc::new(cashierd), executor).await?;
 
     t1.cancel().await;
@@ -760,26 +681,27 @@ async fn main() -> Result<()> {
 
     if args.refresh {
         info!(target: "CASHIER DAEMON", "Refresh the wallet and the database");
+
+        // refresh cashier's client wallet
         let client_wallet_path =
             format!("sqlite://{}", expand_path(&config.client_wallet_path)?.to_str().unwrap());
         let client_wallet =
-            WalletDb::new(&client_wallet_path, config.client_wallet_password.clone()).await?;
-
+            WalletDb::new(&client_wallet_path, &config.client_wallet_password).await?;
         client_wallet.remove_own_coins().await?;
 
+        // refresh cashier wallet
         let wallet_path =
             format!("sqlite://{}", expand_path(&config.cashier_wallet_path)?.to_str().unwrap());
-        let wallet = CashierDb::new(&wallet_path, config.cashier_wallet_password.clone()).await?;
-
+        let wallet = CashierDb::new(&wallet_path, &config.cashier_wallet_password).await?;
         wallet.remove_withdraw_and_deposit_keys().await?;
 
+        // refresh rocks database
         if let Some(path) = expand_path(&config.database_path)?.to_str() {
             info!(target: "CASHIER DAEMON", "Remove database: {}", path);
             std::fs::remove_dir_all(path)?;
         }
 
         info!("Wallet updated successfully.");
-
         return Ok(())
     }
 
@@ -800,47 +722,9 @@ async fn main() -> Result<()> {
             smol::future::block_on(async move {
                 start(ex2, &config, get_address_flag).await?;
                 drop(signal);
-                Ok::<(), drk::Error>(())
+                Ok::<(), darkfi::Error>(())
             })
         });
 
     result
 }
-
-// async fn resume_watch_deposit_keys(
-//     bridge: Arc<Bridge>,
-//     cashier_wallet: Arc<CashierDb>,
-//     networks: Vec<Network>,
-//     executor: Arc<Executor<'_>>,
-// ) -> Result<()> {
-//     debug!(target: "CASHIER DAEMON", "Resume watch deposit keys");
-
-//     for network in networks.iter() {
-//         let keypairs_to_watch =
-//             cashier_wallet.get_deposit_token_keys_by_network(&network.name)?;
-
-//         for deposit_token in keypairs_to_watch {
-//             let bridge = bridge.clone();
-
-//             let bridge_subscribtion = bridge
-//                 .subscribe(
-//                     deposit_token.drk_public_key,
-//                     Some(deposit_token.mint_address),
-//                     executor.clone(),
-//                 )
-//                 .await;
-
-//             bridge_subscribtion
-//                 .sender
-//                 .send(bridge::BridgeRequests {
-//                     network: network.name.clone(),
-//                     payload: bridge::BridgeRequestsPayload::Watch(Some(
-//                         deposit_token.token_key,
-//                     )),
-//                 })
-//                 .await?;
-//         }
-//     }
-
-//     Ok(())
-// }

+ 3 - 3
src/service/bridge.rs → bin/cashier/src/service/bridge.rs

@@ -6,9 +6,9 @@ use async_trait::async_trait;
 use futures::stream::{FuturesUnordered, StreamExt};
 use log::{debug, error};
 
-use crate::{
-    crypto::keypair::PublicKey, types::*, util::NetworkName, wallet::cashierdb::TokenKey, Error,
-    Result,
+use darkfi::{
+    crypto::keypair::PublicKey, node::wallet::cashierdb::TokenKey, types::*, util::NetworkName,
+    Error, Result,
 };
 
 pub struct BridgeRequests {

+ 50 - 16
src/service/btc.rs → bin/cashier/src/service/btc.rs

@@ -41,10 +41,11 @@ use secp256k1::{
 };
 
 use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion};
-use crate::{
+use darkfi::{
     crypto::keypair::PublicKey as DrkPublicKey,
+    node::wallet::cashierdb::{CashierDb, TokenKey},
     serial::{deserialize, serialize, Decodable, Encodable},
-    util::{generate_id2, NetworkName},
+    util::{expand_path, generate_id2, load_keypair_to_str, NetworkName},
     Error, Result,
 };
 
@@ -228,7 +229,7 @@ impl Client {
         let _client = ElectrumClient::from_config(electrum_url, config)?;
 
         let electrum = ElectrumClient::new(electrum_url)
-            .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
+            .map_err(|err| darkfi::Error::from(super::BtcFailed::from(err)))?;
 
         let latest_block = electrum.block_headers_subscribe()?;
 
@@ -239,7 +240,7 @@ impl Client {
             electrum,
             subscriptions: Vec::new(),
             latest_block_height: BlockHeight::try_from(latest_block)
-                .map_err(|_| crate::Error::TryFromError)?,
+                .map_err(|_| darkfi::Error::TryFromError)?,
             last_sync: Instant::now(),
             sync_interval: interval,
             script_history: Default::default(),
@@ -306,7 +307,7 @@ impl Client {
                     Ok(ScriptStatus::InMempool)
                 } else {
                     Ok(ScriptStatus::Confirmed(Confirmed::from_inclusion_and_latest_block(
-                        u32::try_from(last.height).map_err(|_| crate::Error::TryFromError)?,
+                        u32::try_from(last.height).map_err(|_| darkfi::Error::TryFromError)?,
                         u32::from(self.latest_block_height),
                     )))
                 }
@@ -322,7 +323,37 @@ pub struct BtcClient {
     network: Network,
 }
 impl BtcClient {
-    pub async fn new(main_keypair: Keypair, network: &str) -> Result<Arc<Self>> {
+    pub async fn new(
+        cashier_wallet: Arc<CashierDb>,
+        network: &str,
+        keypair_path: &str,
+    ) -> Result<Arc<Self>> {
+        let main_keypair: Keypair;
+
+        let main_keypairs = cashier_wallet.get_main_keys(&NetworkName::Bitcoin).await?;
+
+        if keypair_path.is_empty() {
+            if main_keypairs.is_empty() {
+                main_keypair = Keypair::new();
+                cashier_wallet
+                    .put_main_keys(
+                        &TokenKey {
+                            secret_key: serialize(&main_keypair),
+                            public_key: serialize(&main_keypair.pubkey()),
+                        },
+                        &NetworkName::Bitcoin,
+                    )
+                    .await?;
+            } else {
+                main_keypair = deserialize(&main_keypairs[main_keypairs.len() - 1].secret_key)?;
+            }
+        } else {
+            let keypair_str = load_keypair_to_str(expand_path(&keypair_path)?)?;
+            let keypair_bytes: Vec<u8> = serde_json::from_str(&keypair_str)?;
+            main_keypair = Keypair::from_bytes(&keypair_bytes)
+                .map_err(|e| BtcFailed::DecodeAndEncodeError(e.to_string()))?;
+        }
+
         let notify_channel = async_channel::unbounded();
 
         let (network, url) = match network {
@@ -739,7 +770,7 @@ impl Decodable for bitcoin::Address {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let addr: String = Decodable::decode(&mut d)?;
         let addr = bitcoin::Address::from_str(&addr)
-            .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
+            .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
         Ok(addr)
     }
 }
@@ -756,7 +787,7 @@ impl Decodable for bitcoin::PublicKey {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: Vec<u8> = Decodable::decode(&mut d)?;
         let key = bitcoin::PublicKey::from_slice(&key)
-            .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
+            .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
         Ok(key)
     }
 }
@@ -773,7 +804,7 @@ impl Decodable for bitcoin::PrivateKey {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: String = Decodable::decode(&mut d)?;
         let key = bitcoin::PrivateKey::from_str(&key)
-            .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
+            .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
         Ok(key)
     }
 }
@@ -788,7 +819,7 @@ impl Decodable for secp256k1::key::PublicKey {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: Vec<u8> = Decodable::decode(&mut d)?;
         let key = secp256k1::key::PublicKey::from_slice(&key)
-            .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
+            .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
         Ok(key)
     }
 }
@@ -805,7 +836,7 @@ impl Decodable for Keypair {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: Vec<u8> = Decodable::decode(&mut d)?;
         let key = Keypair::from_bytes(key.as_slice()).map_err(|_| {
-            crate::Error::from(BtcFailed::DecodeAndEncodeError("load keypair from slice".into()))
+            darkfi::Error::from(BtcFailed::DecodeAndEncodeError("load keypair from slice".into()))
         })?;
         Ok(key)
     }
@@ -829,8 +860,8 @@ pub enum BtcFailed {
     Notification(String),
 }
 
-impl From<crate::error::Error> for BtcFailed {
-    fn from(err: crate::error::Error) -> BtcFailed {
+impl From<darkfi::error::Error> for BtcFailed {
+    fn from(err: darkfi::error::Error) -> BtcFailed {
         BtcFailed::BtcError(err.to_string())
     }
 }
@@ -866,11 +897,14 @@ pub type BtcResult<T> = std::result::Result<T, BtcFailed>;
 #[cfg(test)]
 mod tests {
 
-    use super::Keypair;
-    use crate::serial::{deserialize, serialize};
-    use secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE};
     use std::str::FromStr;
 
+    use secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE};
+
+    use darkfi::serial::{deserialize, serialize};
+
+    use super::Keypair;
+
     const KEYPAIR_LENGTH: usize = SECRET_KEY_SIZE + PUBLIC_KEY_SIZE;
 
     #[test]

+ 55 - 16
src/service/eth.rs → bin/cashier/src/service/eth.rs

@@ -13,8 +13,9 @@ use serde_json::{json, Value};
 
 use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion};
 
-use crate::{
+use darkfi::{
     crypto::keypair::PublicKey,
+    node::wallet::cashierdb::{CashierDb, TokenKey},
     rpc::{jsonrpc, jsonrpc::JsonResult},
     serial::{deserialize, serialize, Decodable, Encodable},
     util::{generate_id2, parse::truncate, sleep, NetworkName},
@@ -189,7 +190,7 @@ impl EthTx {
 // INFO [10-25|19:47:32.845] IPC endpoint opened: url=/home/x/.ethereum/ropsten/geth.ipc
 //
 pub struct EthClient {
-    main_keypair: Keypair,
+    pub main_keypair: Keypair,
     passphrase: String,
     socket_path: String,
     subscriptions: Arc<Mutex<Vec<String>>>,
@@ -198,21 +199,59 @@ pub struct EthClient {
 }
 
 impl EthClient {
-    pub fn new(socket_path: String, passphrase: String) -> Self {
+    pub fn new(_network: &str, socket_path: &str, passphrase: &str) -> Self {
         let notify_channel = async_channel::unbounded();
+
         let subscriptions = Arc::new(Mutex::new(Vec::new()));
+
+        let main_keypair = Keypair { public_key: "".into(), private_key: "".into() };
+
         Self {
-            // This must be set by the cashier
-            main_keypair: Keypair { private_key: String::new(), public_key: String::new() },
-            passphrase,
-            socket_path,
+            main_keypair,
+            passphrase: passphrase.into(),
+            socket_path: socket_path.into(),
             subscriptions,
             notify_channel,
         }
     }
 
-    pub fn set_main_keypair(&mut self, keypair: &Keypair) {
-        self.main_keypair = keypair.clone();
+    pub async fn setup_keypair(
+        &mut self,
+        cashier_wallet: Arc<CashierDb>,
+        _keypair_path: &str,
+    ) -> Result<()> {
+        let main_keypair: Keypair;
+
+        let main_keypairs = cashier_wallet.get_main_keys(&NetworkName::Ethereum).await?;
+
+        if main_keypairs.is_empty() {
+            let main_private_key = generate_privkey();
+            let main_public_key =
+                self.import_privkey(&main_private_key).await?.as_str().unwrap().to_string();
+
+            cashier_wallet
+                .put_main_keys(
+                    &TokenKey {
+                        secret_key: serialize(&main_private_key),
+                        public_key: serialize(&main_public_key),
+                    },
+                    &NetworkName::Ethereum,
+                )
+                .await?;
+
+            main_keypair = Keypair { private_key: main_private_key, public_key: main_public_key };
+        } else {
+            let last_keypair = &main_keypairs[main_keypairs.len() - 1];
+
+            main_keypair = Keypair {
+                private_key: deserialize(&last_keypair.secret_key)?,
+                public_key: deserialize(&last_keypair.public_key)?,
+            }
+        }
+
+        self.main_keypair = main_keypair;
+
+        Ok(())
     }
 
     async fn send_eth_to_main_wallet(&self, acc: &str, amount: BigUint) -> Result<()> {
@@ -248,7 +287,7 @@ impl EthClient {
             if sub_iter > 60 * 10 {
                 // 10 minutes
                 self.unsubscribe(&addr).await;
-                return Err(crate::Error::ClientFailed("Deposit for expired".into()))
+                return Err(darkfi::Error::ClientFailed("Deposit for expired".into()))
             }
 
             sub_iter += iter_interval;
@@ -266,7 +305,7 @@ impl EthClient {
         self.unsubscribe(&addr).await;
 
         if current_balance < prev_balance {
-            return Err(crate::Error::ClientFailed(
+            return Err(darkfi::Error::ClientFailed(
                 "New balance is less than previous balance".into(),
             ))
         }
@@ -331,8 +370,8 @@ impl EthClient {
         }
     }
 
-    pub async fn import_privkey(&self, key: &str, passphrase: &str) -> EthResult<Value> {
-        let req = jsonrpc::request(json!("personal_importRawKey"), json!([key, passphrase]));
+    pub async fn import_privkey(&self, key: &str) -> EthResult<Value> {
+        let req = jsonrpc::request(json!("personal_importRawKey"), json!([key, self.passphrase]));
         Ok(self.request(req).await?)
     }
 
@@ -388,7 +427,7 @@ impl NetworkClient for EthClient {
     ) -> Result<TokenSubscribtion> {
         let private_key = generate_privkey();
 
-        let addr = self.import_privkey(&private_key, &self.passphrase).await?;
+        let addr = self.import_privkey(&private_key).await?;
 
         let address: String = if addr.as_str().is_some() {
             addr.as_str().unwrap().to_string()
@@ -492,8 +531,8 @@ pub enum EthFailed {
     ImportPrivateError,
 }
 
-impl From<crate::error::Error> for EthFailed {
-    fn from(err: crate::error::Error) -> EthFailed {
+impl From<darkfi::Error> for EthFailed {
+    fn from(err: darkfi::Error) -> EthFailed {
         EthFailed::EthClientError(err.to_string())
     }
 }

+ 0 - 4
src/service/mod.rs → bin/cashier/src/service/mod.rs

@@ -1,6 +1,4 @@
 pub mod bridge;
-pub mod gateway;
-pub mod reqrep;
 
 #[cfg(feature = "btc")]
 pub mod btc;
@@ -16,5 +14,3 @@ pub use sol::{SolClient, SolFailed, SolResult};
 pub mod eth;
 #[cfg(feature = "eth")]
 pub use eth::{EthClient, EthFailed, EthResult};
-
-pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber};

+ 45 - 8
src/service/sol.rs → bin/cashier/src/service/sol.rs

@@ -12,9 +12,9 @@ use solana_client::{blockhash_query::BlockhashQuery, rpc_client::RpcClient};
 use solana_sdk::{
     native_token::{lamports_to_sol, sol_to_lamports},
     program_pack::Pack,
-    pubkey::Pubkey,
+    pubkey::Pubkey as SolPubkey,
     signature::{Signature, Signer},
-    signer::keypair::Keypair,
+    signer::keypair::Keypair as SolKeypair,
     system_instruction,
     transaction::Transaction,
 };
@@ -23,16 +23,20 @@ use tungstenite::Message;
 
 use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion};
 
-use crate::{
+use darkfi::{
     crypto::keypair::PublicKey,
+    node::wallet::cashierdb::{CashierDb, TokenKey},
     rpc::{jsonrpc, jsonrpc::JsonResult, websockets, websockets::WsStream},
     serial::{deserialize, serialize, Decodable, Encodable},
-    util::{generate_id2, parse::truncate, sleep, NetworkName},
+    util::{expand_path, generate_id2, load_keypair_to_str, parse::truncate, sleep, NetworkName},
     Error, Result,
 };
 
 pub const SOL_NATIVE_TOKEN_ID: &str = "So11111111111111111111111111111111111111112";
 
+struct Keypair(SolKeypair);
+struct Pubkey(SolPubkey);
+
 #[derive(Serialize)]
 struct SubscribeParams {
     encoding: Value,
@@ -50,9 +54,40 @@ pub struct SolClient {
 }
 
 impl SolClient {
-    pub async fn new(main_keypair: Keypair, network: &str) -> Result<Arc<Self>> {
+    pub async fn new(
+        cashier_wallet: Arc<CashierDb>,
+        network: &str,
+        keypair_path: &str,
+    ) -> Result<Arc<Self>> {
         let notify_channel = async_channel::unbounded();
 
+        let main_keypair: Keypair;
+
+        let main_keypairs = cashier_wallet.get_main_keys(&NetworkName::Solana).await?;
+
+        if keypair_path.is_empty() {
+            if main_keypairs.is_empty() {
+                main_keypair = Keypair::new();
+                cashier_wallet
+                    .put_main_keys(
+                        &TokenKey {
+                            secret_key: serialize(&main_keypair),
+                            public_key: serialize(&main_keypair.pubkey()),
+                        },
+                        &NetworkName::Solana,
+                    )
+                    .await?;
+            } else {
+                main_keypair = deserialize(&main_keypairs[main_keypairs.len() - 1].secret_key)?;
+            }
+        } else {
+            let keypair_str = load_keypair_to_str(expand_path(keypair_path)?)?;
+
+            let keypair_bytes: Vec<u8> = serde_json::from_str(&keypair_str)?;
+            main_keypair = Keypair::from_bytes(&keypair_bytes)
+                .map_err(|e| SolFailed::Signature(e.to_string()))?;
+        }
+
         info!(target: "SOL BRIDGE", "Main SOL wallet pubkey: {:?}", &main_keypair.pubkey());
 
         let (rpc_server, wss_server) = match network {
@@ -555,7 +590,7 @@ impl Decodable for Keypair {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: Vec<u8> = Decodable::decode(&mut d)?;
         let key = Keypair::from_bytes(key.as_slice()).map_err(|_| {
-            crate::Error::from(SolFailed::DecodeAndEncodeError("load keypair from slice".into()))
+            darkfi::Error::from(SolFailed::DecodeAndEncodeError("load keypair from slice".into()))
         })?;
         Ok(key)
     }
@@ -573,7 +608,9 @@ impl Decodable for Pubkey {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: String = Decodable::decode(&mut d)?;
         let key = Pubkey::try_from(key.as_str()).map_err(|_| {
-            crate::Error::from(SolFailed::DecodeAndEncodeError("load public key from slice".into()))
+            darkfi::Error::from(SolFailed::DecodeAndEncodeError(
+                "load public key from slice".into(),
+            ))
         })?;
         Ok(key)
     }
@@ -608,7 +645,7 @@ pub enum SolFailed {
     #[error("Signature Error: `{0}`")]
     Signature(String),
     #[error(transparent)]
-    Darkfi(#[from] crate::error::Error),
+    Darkfi(#[from] darkfi::error::Error),
 }
 
 pub type SolResult<T> = std::result::Result<T, SolFailed>;

+ 3 - 0
bin/darkfid/.gitignore

@@ -0,0 +1,3 @@
+
+/target
+Cargo.lock

+ 36 - 0
bin/darkfid/Cargo.toml

@@ -0,0 +1,36 @@
+[package]
+name = "darkfid"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+darkfi = {path= "../../", features= ["node", "chain"] }
+
+# Encoding and parsing
+serde_json = "1.0.72"
+serde = {version = "1.0.130", features = ["derive"]}
+url = "2.2.2"
+
+
+# Async
+async-std = "1.10.0"
+async-trait = "0.1.51"
+async-channel = "1.6.1"
+easy-parallel = "3.1.0"
+async-executor = "1.4.1"
+futures = "0.3.17"
+smol = "1.2.5"
+
+
+# Utilities
+clap = { version = "3.0.0", features = ["derive"] }
+log = "0.4.14"
+simplelog = "0.11.1"
+thiserror = "1.0.30"
+rand = "0.8.4"
+num_cpus = "1.13.0"
+lazy_static = "1.4.0"
+anyhow = "1.0.49"
+num-bigint = {version = "0.4.3", features = ["rand", "serde"]}

+ 24 - 24
src/bin/darkfid.rs → bin/darkfid/src/main.rs

@@ -11,32 +11,36 @@ use serde_json::{json, Value};
 use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 use url::Url;
 
-use drk::{
-    blockchain::{rocks::columns, Rocks, RocksColumn},
-    circuit::{MintContract, SpendContract},
+use darkfi::{
+    chain::{rocks::columns, Rocks, RocksColumn},
     cli::{CliDarkfid, Config, DarkfidConfig},
-    client::Client,
     crypto::{
         keypair::{Keypair, PublicKey, SecretKey},
         proof::VerifyingKey,
     },
-    rpc::{
-        jsonrpc::{
-            error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
-            ErrorCode::*, JsonRequest, JsonResult,
-        },
-        rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
+    node::{
+        client::Client,
+        state::{ProgramState, State},
+        wallet::walletdb::WalletDb,
     },
-    state::{ProgramState, State},
     types::DrkTokenId,
     util::{
-        assign_id, decode_base10, encode_base10, expand_path, join_config_path, Address,
-        DrkTokenList, NetworkName, TokenList,
+        assign_id, decode_base10, encode_base10, expand_path, join_config_path,
+        rpc::{
+            jsonrpc::{
+                error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
+                ErrorCode::*, JsonRequest, JsonResult,
+            },
+            rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
+        },
+        Address, DrkTokenList, NetworkName, TokenList,
     },
-    wallet::walletdb::WalletDb,
+    zk::circuit::{MintContract, SpendContract},
     Error, Result,
 };
 
+pub const ETH_NATIVE_TOKEN_ID: &str = "0x0000000000000000000000000000000000000000";
+
 #[derive(Clone, Debug)]
 pub struct Cashier {
     pub name: String,
@@ -100,11 +104,11 @@ impl Darkfid {
         cashiers: Vec<Cashier>,
     ) -> Result<Self> {
         let sol_tokenlist =
-            TokenList::new(include_bytes!("../../contrib/token/solana_token_list.json"))?;
+            TokenList::new(include_bytes!("../../../contrib/token/solana_token_list.json"))?;
         let eth_tokenlist =
-            TokenList::new(include_bytes!("../../contrib/token/erc20_token_list.json"))?;
+            TokenList::new(include_bytes!("../../../contrib/token/erc20_token_list.json"))?;
         let btc_tokenlist =
-            TokenList::new(include_bytes!("../../contrib/token/bitcoin_token_list.json"))?;
+            TokenList::new(include_bytes!("../../../contrib/token/bitcoin_token_list.json"))?;
         let drk_tokenlist = DrkTokenList::new(&sol_tokenlist, &eth_tokenlist, &btc_tokenlist)?;
 
         Ok(Self {
@@ -395,7 +399,6 @@ impl Darkfid {
         let result: Result<Value> = async {
             let network = NetworkName::from_str(network)?;
             match network {
-                #[cfg(feature = "sol")]
                 NetworkName::Solana => {
                     if let Some(tkn) = self.sol_tokenlist.search_id(symbol)? {
                         Ok(json!(tkn))
@@ -403,7 +406,6 @@ impl Darkfid {
                         Err(Error::NotSupportedToken)
                     }
                 }
-                #[cfg(feature = "btc")]
                 NetworkName::Bitcoin => {
                     if let Some(tkn) = self.btc_tokenlist.search_id(symbol)? {
                         Ok(json!(tkn))
@@ -411,10 +413,8 @@ impl Darkfid {
                         Err(Error::NotSupportedToken)
                     }
                 }
-                #[cfg(feature = "eth")]
                 NetworkName::Ethereum => {
                     if symbol.to_lowercase() == "eth" {
-                        use drk::service::eth::ETH_NATIVE_TOKEN_ID;
                         Ok(json!(ETH_NATIVE_TOKEN_ID.to_string()))
                     } else if let Some(tkn) = self.eth_tokenlist.search_id(symbol)? {
                         Ok(json!(tkn))
@@ -713,7 +713,7 @@ async fn start(
     config: &DarkfidConfig,
 ) -> Result<()> {
     let wallet_path = format!("sqlite://{}", expand_path(&config.wallet_path)?.to_str().unwrap());
-    let wallet = WalletDb::new(&wallet_path, config.wallet_password.clone()).await?;
+    let wallet = WalletDb::new(&wallet_path, &config.wallet_password).await?;
 
     let rocks = Rocks::new(expand_path(&config.database_path.clone())?.as_path())?;
 
@@ -821,7 +821,7 @@ async fn main() -> Result<()> {
         info!(target: "DARKFI DAEMON", "Refresh the wallet and the database");
         let wallet_path =
             format!("sqlite://{}", expand_path(&config.wallet_path)?.to_str().unwrap());
-        let wallet = WalletDb::new(&wallet_path, config.wallet_password.clone()).await?;
+        let wallet = WalletDb::new(&wallet_path, &config.wallet_password).await?;
 
         wallet.remove_own_coins().await?;
 
@@ -850,7 +850,7 @@ async fn main() -> Result<()> {
             smol::future::block_on(async move {
                 start(ex2, args.cashier, &config).await?;
                 drop(signal);
-                Ok::<(), drk::Error>(())
+                Ok::<(), darkfi::Error>(())
             })
         });
 

+ 3 - 0
bin/drk/.gitignore

@@ -0,0 +1,3 @@
+
+/target
+Cargo.lock

+ 26 - 0
bin/drk/Cargo.toml

@@ -0,0 +1,26 @@
+[package]
+name = "drk"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+darkfi = {path= "../../"}
+
+# Encoding and parsing
+serde_json = "1.0.72"
+serde = {version = "1.0.130", features = ["derive"]}
+
+# Async
+async-std = {version = "1.10.0", features = ["attributes"]}
+async-executor = "1.4.1"
+futures = "0.3.17"
+smol = "1.2.5"
+
+
+# Utilities
+clap = { version = "3.0.0", features = ["derive"] }
+prettytable-rs = "0.8.0"
+simplelog = "0.11.1"
+log = "0.4.14"

+ 7 - 3
src/bin/drk.rs → bin/drk/src/main.rs

@@ -8,10 +8,14 @@ use prettytable::{format, Table};
 use serde_json::{json, Value};
 use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 
-use drk::{
+use darkfi::{
     cli::{CliDrk, CliDrkSubCommands, Config, DrkConfig},
-    rpc::{jsonrpc, jsonrpc::JsonResult},
-    util::{join_config_path, path::expand_path, NetworkName},
+    util::{
+        join_config_path,
+        path::expand_path,
+        rpc::{jsonrpc, jsonrpc::JsonResult},
+        NetworkName,
+    },
     Error, Result,
 };
 

+ 3 - 0
bin/gateway/.gitignore

@@ -0,0 +1,3 @@
+
+/target
+Cargo.lock

+ 29 - 0
bin/gateway/Cargo.toml

@@ -0,0 +1,29 @@
+[package]
+name = "gateway"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+darkfi = {path= "../../", features= ["node", "chain"] }
+
+# Async
+async-std = "1.10.0"
+async-channel = "1.6.1"
+easy-parallel = "3.1.0"
+async-executor = "1.4.1"
+futures = "0.3.17"
+smol = "1.2.5"
+
+# Utilities
+clap = { version = "3.0.0", features = ["derive"] }
+log = "0.4.14"
+num_cpus = "1.13.0"
+simplelog = "0.11.1"
+thiserror = "1.0.30"
+rand = "0.8.4"
+
+# Encoding and parsing
+bytes = "1.1.0"
+url = "2.2.2"

+ 4 - 4
src/bin/gatewayd.rs → bin/gateway/src/main.rs

@@ -6,10 +6,10 @@ use easy_parallel::Parallel;
 use log::debug;
 use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 
-use drk::{
-    blockchain::{rocks::columns, Rocks, RocksColumn},
+use darkfi::{
+    chain::{rocks::columns, Rocks, RocksColumn},
     cli::{CliGatewayd, Config, GatewaydConfig},
-    service::GatewayService,
+    node::service::gateway::GatewayService,
     util::{expand_path, join_config_path},
     Result,
 };
@@ -70,7 +70,7 @@ async fn main() -> Result<()> {
             smol::future::block_on(async move {
                 start(ex2, &config).await?;
                 drop(signal);
-                Ok::<(), drk::Error>(())
+                Ok::<(), darkfi::Error>(())
             })
         });
 

+ 8 - 13
bin/ircd/src/irc_server.rs

@@ -1,17 +1,10 @@
-use std::{
-    net::{TcpStream},
-};
-use rand::{RngCore, rngs::OsRng};
-use futures::{
-    io::{WriteHalf}, AsyncWriteExt,
-};
+use futures::{io::WriteHalf, AsyncWriteExt};
 use log::{debug, info};
+use rand::{rngs::OsRng, RngCore};
 use smol::Async;
+use std::net::TcpStream;
 
-use drk::{
-    net,
-    Error, Result,
-};
+use darkfi::{net, Error, Result};
 
 use crate::privmsg::{PrivMsg, SeenPrivMsgIdsPtr};
 
@@ -43,7 +36,10 @@ pub struct IrcServerConnection {
 }
 
 impl IrcServerConnection {
-    pub fn new(write_stream: WriteHalf<Async<TcpStream>>, seen_privmsg_ids: SeenPrivMsgIdsPtr) -> Self {
+    pub fn new(
+        write_stream: WriteHalf<Async<TcpStream>>,
+        seen_privmsg_ids: SeenPrivMsgIdsPtr,
+    ) -> Self {
         Self {
             write_stream,
             seen_privmsg_ids,
@@ -140,4 +136,3 @@ impl IrcServerConnection {
         Ok(())
     }
 }
-

+ 33 - 26
bin/ircd/src/main.rs

@@ -1,43 +1,44 @@
 #[macro_use]
 extern crate clap;
-use async_trait::async_trait;
-use std::{
-    net::{SocketAddr, TcpListener, TcpStream},
-    sync::Arc,
-};
 use async_executor::Executor;
 use async_std::io::BufReader;
-use futures::{
-    AsyncBufReadExt, AsyncReadExt, FutureExt,
-};
-use serde_json::{json, Value};
+use async_trait::async_trait;
+use futures::{AsyncBufReadExt, AsyncReadExt, FutureExt};
 use log::{debug, error, info, warn};
+use serde_json::{json, Value};
 use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 use smol::Async;
+use std::{
+    net::{SocketAddr, TcpListener, TcpStream},
+    sync::Arc,
+};
 
-use drk::{
+use darkfi::{
     net,
-    util::{expand_path, sleep},
-    rpc::{
-        jsonrpc::{
-            error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
-            ErrorCode::*, JsonRequest, JsonResult,
+    util::{
+        expand_path,
+        rpc::{
+            jsonrpc::{
+                error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
+                ErrorCode::*, JsonRequest, JsonResult,
+            },
+            rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
         },
-        rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
+        sleep,
     },
     Error, Result,
 };
 
+mod irc_server;
 mod privmsg;
 mod program_options;
 mod protocol_privmsg;
-mod irc_server;
 
 use crate::{
+    irc_server::IrcServerConnection,
     privmsg::{PrivMsg, PrivMsgId, SeenPrivMsgIds, SeenPrivMsgIdsPtr},
     program_options::ProgramOptions,
     protocol_privmsg::ProtocolPrivMsg,
-    irc_server::IrcServerConnection,
 };
 
 async fn process(
@@ -114,7 +115,10 @@ async fn channel_loop(
     loop {
         let channel = new_channel_sub.receive().await?;
 
-        let protocol_privmsg = ProtocolPrivMsg::new(channel, sender.clone(), seen_privmsg_ids.clone(), p2p.clone()).await;
+        let protocol_privmsg =
+            ProtocolPrivMsg::new(channel, sender.clone(), seen_privmsg_ids.clone(), p2p.clone())
+                .await;
+
         protocol_privmsg.start(executor.clone()).await;
     }
 }
@@ -164,14 +168,16 @@ async fn start(executor: Arc<Executor<'_>>, options: ProgramOptions) -> Result<(
     let (sender, recvr) = async_channel::unbounded();
     // for now the p2p and channel sub sessions just run forever
     // so detach them as background processes.
-    executor.spawn(channel_loop(p2p.clone(), sender, seen_privmsg_ids.clone(), executor.clone())).detach();
+    executor
+        .spawn(channel_loop(p2p.clone(), sender, seen_privmsg_ids.clone(), executor.clone()))
+        .detach();
 
     let ex2 = executor.clone();
     let ex3 = ex2.clone();
     let rpc_interface = Arc::new(JsonRpcInterface {});
-    executor.spawn(async move {
-        listen_and_serve(server_config, rpc_interface, ex3).await
-    }).detach();
+    executor
+        .spawn(async move { listen_and_serve(server_config, rpc_interface, ex3).await })
+        .detach();
 
     loop {
         let (stream, peer_addr) = match listener.accept().await {
@@ -185,12 +191,13 @@ async fn start(executor: Arc<Executor<'_>>, options: ProgramOptions) -> Result<(
 
         let p2p2 = p2p.clone();
         let ex2 = executor.clone();
-        executor.spawn(process(recvr.clone(), stream, peer_addr, p2p2, seen_privmsg_ids.clone(), ex2)).detach();
+        executor
+            .spawn(process(recvr.clone(), stream, peer_addr, p2p2, seen_privmsg_ids.clone(), ex2))
+            .detach();
     }
 }
 
-struct JsonRpcInterface {
-}
+struct JsonRpcInterface {}
 
 #[async_trait]
 impl RequestHandler for JsonRpcInterface {

+ 4 - 8
bin/ircd/src/privmsg.rs

@@ -1,13 +1,10 @@
 use async_std::sync::Mutex;
-use std::{
-    collections::HashSet,
-    io,
-    sync::Arc,
-};
-use drk::{
+use darkfi::{
     net,
-    serial::{Decodable, Encodable}, Result,
+    serial::{Decodable, Encodable},
+    Result,
 };
+use std::{collections::HashSet, io, sync::Arc};
 
 pub type PrivMsgId = u32;
 
@@ -66,4 +63,3 @@ impl SeenPrivMsgIds {
         self.privmsg_ids.lock().await.contains(&id)
     }
 }
-

+ 2 - 14
bin/ircd/src/program_options.rs

@@ -1,17 +1,6 @@
-use std::{
-    net::{SocketAddr},
-};
+use std::net::SocketAddr;
 
-
-
-
-
-
-
-
-use drk::{
-    net, Result,
-};
+use darkfi::{net, Result};
 
 pub struct ProgramOptions {
     pub network_settings: net::Settings,
@@ -96,4 +85,3 @@ impl ProgramOptions {
         })
     }
 }
-

+ 4 - 10
bin/ircd/src/protocol_privmsg.rs

@@ -1,15 +1,10 @@
+use async_executor::Executor;
 use async_std::sync::Mutex;
-use std::{
-    sync::Arc,
-    collections::HashSet,
-};
+use darkfi::{net, Result};
 use log::debug;
-use async_executor::Executor;
-use drk::{
-    net, Result,
-};
+use std::{collections::HashSet, sync::Arc};
 
-use crate::privmsg::{PrivMsgId, PrivMsg, SeenPrivMsgIdsPtr};
+use crate::privmsg::{PrivMsg, PrivMsgId, SeenPrivMsgIdsPtr};
 
 pub struct ProtocolPrivMsg {
     notify_queue_sender: async_channel::Sender<Arc<PrivMsg>>,
@@ -76,4 +71,3 @@ impl ProtocolPrivMsg {
         }
     }
 }
-

+ 1 - 1
bin/map/Cargo.toml

@@ -4,7 +4,7 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-darkfi = { path = "../../" , features = ['tui']}
+#darkfi = { path = "../../" , features = ['tui']}
 smol = "1.2.5"
 tui = "0.16.0"
 termion = "1.5"

+ 89 - 0
bin/map/src/app.rs

@@ -0,0 +1,89 @@
+use crate::list::StatefulList;
+
+pub struct App<'a> {
+    pub nodes: StatefulList<(&'a str)>,
+}
+
+impl<'a> App<'a> {
+    pub fn new() -> App<'a> {
+        App {
+            nodes: StatefulList::with_items(vec![
+                ("node0"),
+                ("node1"),
+                ("node2"),
+                ("node3"),
+                ("node4"),
+                ("node5"),
+                ("node6"),
+                ("node7"),
+                ("node8"),
+                ("node9"),
+                ("node10"),
+                ("node11"),
+                ("node12"),
+                ("node13"),
+                ("node14"),
+                ("node15"),
+                ("node16"),
+                ("node17"),
+                ("node18"),
+                ("node19"),
+                ("node20"),
+                ("node21"),
+                ("node22"),
+                ("node23"),
+                ("node24"),
+                ("node0"),
+                ("node1"),
+                ("node2"),
+                ("node3"),
+                ("node4"),
+                ("node5"),
+                ("node6"),
+                ("node7"),
+                ("node8"),
+                ("node9"),
+                ("node10"),
+                ("node11"),
+                ("node12"),
+                ("node13"),
+                ("node14"),
+                ("node15"),
+                ("node16"),
+                ("node17"),
+                ("node18"),
+                ("node19"),
+                ("node20"),
+                ("node21"),
+                ("node22"),
+                ("node23"),
+                ("node24"),
+                ("node0"),
+                ("node1"),
+                ("node2"),
+                ("node3"),
+                ("node4"),
+                ("node5"),
+                ("node6"),
+                ("node7"),
+                ("node8"),
+                ("node9"),
+                ("node10"),
+                ("node11"),
+                ("node12"),
+                ("node13"),
+                ("node14"),
+                ("node15"),
+                ("node16"),
+                ("node17"),
+                ("node18"),
+                ("node19"),
+                ("node20"),
+                ("node21"),
+                ("node22"),
+                ("node23"),
+                ("node24"),
+            ]),
+        }
+    }
+}

+ 44 - 0
bin/map/src/list.rs

@@ -0,0 +1,44 @@
+use tui::widgets::ListState;
+
+pub struct StatefulList<T> {
+    pub state: ListState,
+    pub items: Vec<T>,
+}
+
+impl<T> StatefulList<T> {
+    pub fn with_items(items: Vec<T>) -> StatefulList<T> {
+        StatefulList { state: ListState::default(), items }
+    }
+
+    pub fn next(&mut self) {
+        let i = match self.state.selected() {
+            Some(i) => {
+                if i >= self.items.len() - 1 {
+                    0
+                } else {
+                    i + 1
+                }
+            }
+            None => 0,
+        };
+        self.state.select(Some(i));
+    }
+
+    pub fn previous(&mut self) {
+        let i = match self.state.selected() {
+            Some(i) => {
+                if i == 0 {
+                    self.items.len() - 1
+                } else {
+                    i - 1
+                }
+            }
+            None => 0,
+        };
+        self.state.select(Some(i));
+    }
+
+    pub fn unselect(&mut self) {
+        self.state.select(None);
+    }
+}

+ 41 - 36
bin/map/src/main.rs

@@ -1,62 +1,67 @@
-use rand::{thread_rng, Rng};
-use std::{io, io::Read, time::Instant};
+use std::{
+    io,
+    io::Read,
+    time::{Duration, Instant},
+};
 use termion::{async_stdin, event::Key, input::TermRead, raw::IntoRawMode};
 use tui::{
-    backend::TermionBackend,
-    layout::{Constraint, Direction, Layout},
-    style::{Color, Style},
-    text::Spans,
-    widgets::{Block, Borders, Paragraph},
+    backend::{Backend, TermionBackend},
     Terminal,
 };
 
+pub mod app;
+pub mod list;
+pub mod ui;
+
+use crate::app::App;
+
 fn main() -> Result<(), io::Error> {
     // Set up terminal output
     let stdout = io::stdout().into_raw_mode()?;
     let backend = TermionBackend::new(stdout);
     let mut terminal = Terminal::new(backend)?;
 
-    // Create a separate thread to poll stdin.
-    // This provides non-blocking input support.
+    // create app and run it
+    let tick_rate = Duration::from_millis(250);
+    let app = App::new();
+    let res = run_app(&mut terminal, app, tick_rate);
+
+    terminal.clear()?;
+
+    if let Err(err) = res {
+        println!("{:?}", err)
+    }
+
+    Ok(())
+}
+
+fn run_app<B: Backend>(
+    terminal: &mut Terminal<B>,
+    mut app: App,
+    tick_rate: Duration,
+) -> io::Result<()> {
     let mut asi = async_stdin();
 
-    let mut then = Instant::now();
-    let mut rng = thread_rng();
-    // Clear the terminal before first draw.
     terminal.clear()?;
+
+    let mut last_tick = Instant::now();
     loop {
-        // Lock the terminal and start a drawing session.
-        terminal.draw(|frame| {
-            // Create a layout into which to place our blocks.
-            let size = frame.size();
-
-            // The text lines for our text box.
-            let txt = vec![Spans::from("\n Press q to quit.\n")];
-            // Create a paragraph with the above text...
-            let graph = Paragraph::new(txt)
-                // In a block with borders and the given title...
-                .block(Block::default().title("List of active nodes").borders(Borders::ALL))
-                // With white foreground and black background...
-                .style(Style::default().fg(Color::White).bg(Color::Black));
-
-            // Render into the second chunk of the layout.
-            frame.render_widget(graph, size);
-        })?;
-
-        // Iterate over all the keys that have been pressed since the
-        // last time we checked.
+        terminal.draw(|f| ui::ui(f, &mut app))?;
+
         for k in asi.by_ref().keys() {
             match k.unwrap() {
-                // If any of them is q, quit
                 Key::Char('q') => {
-                    // Clear the terminal before exit so as not to leave
-                    // a mess.
                     terminal.clear()?;
                     return Ok(())
                 }
-                // Otherwise, throw them away.
+                Key::Char('j') => app.nodes.next(),
+                Key::Char('k') => app.nodes.previous(),
                 _ => (),
             }
         }
+
+        if last_tick.elapsed() >= tick_rate {
+            last_tick = Instant::now();
+        }
     }
 }

+ 7 - 0
bin/map/src/mod.rs

@@ -0,0 +1,7 @@
+pub mod list;
+pub mod app;
+pub mod ui;
+
+pub use list::StatefulList;
+pub use app::App;
+pub use ui::ui;

+ 31 - 0
bin/map/src/ui.rs

@@ -0,0 +1,31 @@
+use crate::app::App;
+use tui::{
+    backend::Backend,
+    style::{Color, Modifier, Style},
+    text::{Spans},
+    widgets::{Block, Borders, List, ListItem},
+    Frame,
+};
+
+pub fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
+    let size = f.size();
+
+    let items: Vec<ListItem> = app
+        .nodes
+        .items
+        .iter()
+        .map(|i| {
+            let lines = vec![Spans::from(i.to_string())];
+            ListItem::new(lines).style(Style::default())
+        })
+        .collect();
+
+    // Create a List from all list items and highlight the currently selected one
+    let items = List::new(items)
+        .block(Block::default().borders(Borders::ALL).title("List of nodes"))
+        .highlight_style(Style::default().bg(Color::Black).add_modifier(Modifier::BOLD))
+        .highlight_symbol(">> ");
+
+    // Render the item list
+    f.render_stateful_widget(items, size, &mut app.nodes.state);
+}

+ 1 - 0
book/src/SUMMARY.md

@@ -10,3 +10,4 @@
   - [Bincode](zkas/bincode.md)
   - [Examples](zkas/examples.md)
     - [Sapling scheme](zkas/examples/sapling.md)
+    - [Anonymous voting](zkas/examples/voting.md)

+ 102 - 79
book/src/zkas/examples/sapling.md

@@ -1,18 +1,22 @@
 # Sapling payment scheme
 
-Generally, the Sapling payment scheme consists of two proofs -
+Sapling is a type of transaction which hides both the sender and
+receiver data, as well as the amount transacted. This means it allows
+a fully private transaction between two addresses.
+
+Generally, the Sapling payment scheme consists of two ZK proofs -
 **mint** and **burn**. We use the mint proof to create a new _coin_
 $C$, and we use the burn proof to spend a previously minted _coin_.
 
-## Mint
+## Mint proof
 
 ```
 {{#include ../../../../zkas/proofs/mint.zk}}
 ```
 
-As you can see, the `Mint` contract/circuit basically consists of
-three operations. First one is hashing the _coin_ $C$, and after
-that, we create _Pedersen commitments_ for both the coin's **value**
+As you can see, the `Mint` proof basically consists of three
+operations.  First one is hashing the _coin_ $C$, and after that,
+we create _Pedersen commitments_[^1] for both the coin's **value**
 and the coin's **token ID**. On top of the zkas code, we've declared
 two constant values that we are going to use for multiplication in
 the commitments.
@@ -20,25 +24,25 @@ the commitments.
 The `constrain_instance` call can take any of our assigned variables
 and enforce a _public input_. Public inputs are an array (or vector)
 of values used as public inputs by verifiers to verify a zero knowledge
-proof. In the above case of the Mint contract, since we have five
-calls to `constrain_instance`, we would also have an array of five
-elements that represent these public inputs. The array's order **must**
-match the `constrain_instance` calls since they will be constrained
+proof. In the above case of the Mint proof, since we have five calls to
+`constrain_instance`, we would also have an array of five elements that
+represent these public inputs. The array's order **must match** the
+order of the `constrain_instance` calls since they will be constrained
 by their index in the array (which is incremented for every call).
 
 In other words, the vector of public inputs could look like this:
 
-```rust
+```
 let public_inputs = vec![
     coin,
-    *value_commitment_coords.x(),
-    *value_commitment_coords.y(),
-    *token_commitment_coords.x(),
-    *token_commitment_coords.y(),
+    *value_coords.x();
+    *value_coords.y();
+    *token_coords.x();
+    *token_coords.y();
 ];
 ```
 
-And then the Verifier uses these public inputs to verify a given zero 
+And then the Verifier uses these public inputs to verify a given zero
 knowledge proof.
 
 ### Coin
@@ -49,30 +53,37 @@ blockchain and added to the Merkle tree.
 
 Let $v$ be the coin's value, $t$ be the token ID, $\rho$ be the unique
 serial number for the coin, and $r_C$ be a random blinding value. We
-create a commitment (hash) these elements and produce the coin $C$ in
-zero-knowledge:
+create a commitment (hash) of these elements and produce the coin $C$
+in zero-knowledge:
 
-$$C = H(P, v, t, \rho, r_C)$$
+$$ C = H(P, v, t, \rho, r_C)$$
 
-### Value and Token commitments
+An interesting thing to keep in mind is that this commitment is
+extensible, so one could fit an arbitrary amount of different
+attributes inside it.
 
-To have some value $v$ for our coin, we can create a
-_Pedersen commitment_ $V$ where $r_V$ is the blinding factor for the
-commitment, and $G_1$ and $G_2$ are two predefined generators:
+### Value and token commitments
+
+To have some value $v$ for our coin, we ensure it's greater than
+zero, and then we can create a Pedersen commitment $V$ where $r_V$
+is the blinding factor for the commitment, and $G_1$ and $G_2$ are
+two predefined generators:
 
 $$ v > 0 $$
 $$ V = vG_1 + r_VG_2 $$
 
-The token ID can be thought of as an attribute we append to our _coin_
+The token ID can be thought of as an attribute we append to our coin
 so we can have a differentiation of assets we are working with. In
-practice for example, this allows us to work with different tokens,
-using the same zero-knowledge proof circuit. For this token ID, we can
-also build a _Pedersen commitment_ $T$, where $t$ is the token ID,
-$r_T$ is the blinding factor, and $G_1$ and $G_2$ are the generators:
+practice, this allows us to work with different tokens, using the
+same zero-knowledge proof circuit. For this token ID, we can also
+build a Pedersen commitment $T$ where $t$ is the token ID, $r_T$
+is the blinding factor, and $G_1$ and $G_2$ are predefined generators:
 
 $$ T = tG_1 + r_TG_2 $$
 
-Knowing this, we can extend our code example and build the
+## Pseudo-code
+
+Knowing this we can extend our pseudo-code and build the
 before-mentioned public inputs for the circuit:
 
 ```rust
@@ -88,43 +99,46 @@ let coin_blind = pallas::Base::random(&mut OsRng);
 
 let coin = poseidon::Hash(pub_x, pub_y, value, token, serial, coin_blind);
 
-let value_commit = pedersen_commitment_u64(value, value_blind);
+let value_blind = pallas::Scalar::random(&mut OsRng);
+let value_commit = pedersen_commitment(value, value_blind);
 let value_coords = value_commit.to_affine().coordinates().unwrap();
 
-let token_commit = pedersen_commitment_u64(token, token_blind);
+let token_blind = pallas::Scalar::random(&mut OsRng);
+let token_commit = pedersen_commitment(token, token_blind);
 let token_coords = token_commit.to_affine().coordinates().unwrap();
 
 let public_inputs = vec![
     coin,
-    *value_commitment_coords.x(),
-    *value_commitment_coords.y(),
-    *token_commitment_coords.x(),
-    *token_commitment_coords.y(),
+    *value_coords.x(),
+    *value_coords.y(),
+    *token_coords.x(),
+    *token_coords.y(),
 ];
 ```
 
+
 ## Burn
 
 ```
 {{#include ../../../../zkas/proofs/burn.zk}}
 ```
 
-The `Burn` contract/circuit consists of operations similar to the
-`Mint` circuit, with the addition of _Merkle root_ calculation. In
-the same manner, we're doing a Poseidon hash instance, we're building
-Pedersen commitments for the value and token ID, and finally we're
-doing a public key derivation.
+The `Burn` proof consists of operations similar to the `Mint` proof,
+with the addition of a _Merkle root_[^2] calculation. In the same
+manner, we are doing a Poseidon hash instance, we're building Pedersen
+commitments for the value and token ID, and finally we're doing a
+public key derivation.
 
 In this case, our vector of public inputs could look like:
 
-```rust
+```
 let public_inputs = vec![
     nullifier,
-    *value_commitment_coords.x(),
-    *value_commitment_coords.y(),
-    *token_commitment_coords.x(),
-    *token_commitment_coords.y(),
     merkle_root,
+    *value_coords.x(),
+    *value_coords.y(),
+    *token_coords.x(),
+    *token_coords.y(),
     *signature_coords.x(),
     *signature_coords.y(),
 ];
@@ -141,9 +155,17 @@ are unique per coin and prevent double spending:
 $$ N = H(x, \rho) $$
 
 
-### Value and Token commitments
+### Merkle root
+
+We check that the merkle root corresponds to a coin which is in the
+Merkle tree $R$
+
+$$ C = H(P, v, t, \rho, r_C) $$
+$$ C \in R $$
+
+### Value and token commitments
 
-Just like we calculated these for the `Mint` contract, we do the same
+Just like we calculated these for the `Mint` proof, we do the same
 here:
 
 $$ v > 0 $$
@@ -151,23 +173,18 @@ $$ V = vG_1 + r_VG_2 $$
 $$ T = tG_1 + r_TG_2 $$
 
 
-### Public key derivation
+## Public key derivation
 
 We check that the secret key $x$ corresponds to a public key $P$.
-Usually, we do public key derivation by multiplying our secret key
-with a generator $G$, which results in a public key.
+Usually, we do public key derivation my multiplying our secret key
+with a genera tor $G$, which results in a public key:
 
 $$ P = xG $$
 
-### Merkle root
-
-We check that the merkle root corresponds to a coin which is in the
-Merkle tree $R$:
 
-$$ C = H(P, v, t, \rho, r_C) $$
-$$ C \in R $$
+## Pseudo-code
 
-Knowing this, we can extend our code example and build the
+Knowing this we can extend our pseudo-code and build the
 before-mentioned public inputs for the circuit:
 
 ```rust
@@ -176,39 +193,45 @@ let serial = pallas::Base::random(&mut OsRng);
 
 let nullifier = poseidon::Hash(secret_key, serial);
 
-let value = 42;
-let token = 1;
-let value_blind = pallas::Scalar::random(&mut OsRng);
-let token_blind = pallas::Scalar::random(&mut OsRng);
-
-let value_commit = pedersen_commitment_u64(value, valie_blind);
-let value_coords = value_commit.to_affine().coordinates().unwrap();
-
-let token_commit = pedersen_commitment_u64(token, token_blind);
-let token_coords = token_commit.to_affine().coordinates().unwrap();
-
 let tree = BridgeTree::<MerkleNode, 32>::new(100);
-let some_coin_0 = pallas::Base::random(&mut OsRng);
-let some_coin_1 = pallas::Base::random(&mut OsRng);
-tree.append(some_coin_0);
+tree.append(some_known_coin);
 tree.witness();
-tree.append(some_coin_1);
+tree.append(another_known_coin);
 tree.witness();
 
 let merkle_root = tree.root();
 
+let value = pallas::Base::from(42);
+let token = pallas::Base::from(1);
+
+let value_blind = pallas::Scalar::random(&mut OsRng);
+let value_commit = pedersen_commitment(value, value_blind);
+let value_coords = value_commit.to_affine().coordinates().unwrap();
+
+let token_blind = pallas::Scalar::random(&mut OsRng);
+let token_commit = pedersen_commitment(token, token_blind);
+let token_coords = token_commit.to_affine().coordinates().unwrap();
+
 let sig_secret = pallas::Base::random(&mut OsRng);
-let sig_public = OrchardFixedBases::NullifierK.generator() * mod_r_p(sig_secret);
-let sig_coords = sig_public.to_affine().coordinates().unwrap();
+let sig_public = NullifierK.generator() * mod_r_p(sig_secret);
+let signature_coords = sig_public.to_affine().coordinates().unwrap();
 
 let public_inputs = vec![
     nullifier,
-    *value_commit_coords.x(),
-    *value_commit_coords.y(),
-    *token_commit_coords.x(),
-    *token_commit_coords.y(),
     merkle_root,
-    *sig_coords.x(),
-    *sig_coords.y(),
+    *value_coords.x(),
+    *value_coords.y(),
+    *token_coords.x(),
+    *token_coords.y(),
+    *signature_coords.x(),
+    *signature_coords.y(),
 ];
 ```
+
+
+[^1]: See section 3: _The Commitment Scheme_ of Torben Pryds Pedersen's
+    [paper on Non-Interactive and
+    Information-Theoretic Secure Verifiable Secret
+    Sharing](https://link.springer.com/content/pdf/10.1007%2F3-540-46766-1_9.pdf)
+
+[^2]: [Merkle tree on Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree)

+ 50 - 0
book/src/zkas/examples/voting.md

@@ -0,0 +1,50 @@
+Anonymous voting
+================
+
+Anonymous voting[^1] is a type of voting process where users can
+vote without revealing their identity, by proving they are accepted
+as valid voters.
+
+The proof enables user privacy and allows for fully anonymous voting.
+
+The starting point is a Merkle proof[^2], which efficiently proves that
+a voter's key belongs to a Merkle tree. However, using this proof alone
+would allow the organizer of a process to correlate each vote envelope
+with its voter's key on the database, so votes wouldn't be secret.
+
+## Vote proof
+
+```
+{{#include ../../../../zkas/proofs/voting.zk}}
+```
+
+Our proof consists of four main operation. First we are hashing the
+_nullifier_ using our secret key and the hashed process ID. Next,
+we derive our public key and hash it. Following, we take this hash
+and create a Merkle proof that it is indeed contained in the given
+Merkle tree. And finally, we create a _Pedersen commitment_[^3]
+for the vote choice itself.
+
+Our vector of public inputs can look like this:
+
+```
+let public_inputs = vec![
+    nullifier,
+    merkle_root,
+    *vote_coords.x(),
+    *vote_coords.y(),
+]
+```
+
+And then the Verifier uses these public inputs to verify the given
+zero-knowledge proof.
+
+[^1]: Specification taken from [vocdoni franchise proof](https://docs.vocdoni.io/architecture/protocol/anonymous-voting/zk-census-proof.html)
+
+[^2]: [Merkle tree on Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree)
+
+[^3]: See section 3: _The Commitment Scheme_ of Torben Pryds Pedersen's
+    [paper on Non-Interactive and
+    Information-Theoretic Secure Verifiable Secret
+    Sharing](https://link.springer.com/content/pdf/10.1007%2F3-540-46766-1_9.pdf)
+

+ 1 - 1
contrib/zk.lua

@@ -23,7 +23,7 @@ local keyword = token(l.KEYWORD, word_match{
 -- Types.
 local type = token(l.TYPE, word_match{
   'EcPoint', 'EcFixedPoint', 'Base', 'BaseArray',
-  'Scalar', 'ScalarArray', 'MerklePath',
+  'Scalar', 'ScalarArray', 'MerklePath', 'Uint32',
 })
 
 -- Instructions.

+ 1 - 1
example/net.rs

@@ -3,7 +3,7 @@ use std::{net::SocketAddr, str::FromStr, sync::Arc};
 use async_executor::Executor;
 use clap::Parser;
 
-use drk::{net, Result};
+use darkfi::{net, Result};
 
 async fn start(executor: Arc<Executor<'_>>, options: ProgramOptions) -> Result<()> {
     let p2p = net::P2p::new(options.network_settings);

+ 1 - 1
src/bin/tree.rs → example/tree.rs

@@ -2,7 +2,7 @@ use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
 use pasta_curves::{arithmetic::Field, pallas};
 use rand::rngs::OsRng;
 
-use drk::{crypto::merkle_node::MerkleNode, Result};
+use darkfi::{crypto::merkle_node::MerkleNode, Result};
 
 fn main() -> Result<()> {
     let mut tree = BridgeTree::<MerkleNode, 32>::new(100);

+ 1 - 1
src/bin/tui_ex.rs → example/tui_ex.rs

@@ -1,4 +1,4 @@
-use drk::{
+use darkfi::{
     tui::{App, HBox, VBox, Widget},
     Result,
 };

+ 3 - 3
src/bin/tx.rs → example/tx.rs

@@ -1,8 +1,7 @@
 use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
 use rand::rngs::OsRng;
 
-use drk::{
-    circuit::{mint_contract::MintContract, spend_contract::SpendContract},
+use darkfi::{
     crypto::{
         coin::Coin,
         keypair::{Keypair, PublicKey, SecretKey},
@@ -11,9 +10,10 @@ use drk::{
         nullifier::Nullifier,
         proof::{ProvingKey, VerifyingKey},
     },
-    state::{state_transition, ProgramState, StateUpdate},
+    node::state::{state_transition, ProgramState, StateUpdate},
     tx,
     util::{generate_id2, NetworkName},
+    zk::circuit::{mint_contract::MintContract, spend_contract::SpendContract},
     Result,
 };
 

+ 3 - 3
src/bin/vm.rs → example/vm.rs

@@ -11,14 +11,14 @@ use pasta_curves::{
 use rand::rngs::OsRng;
 use std::{collections::HashMap, fs::File, time::Instant};
 
-use drk::{
+use darkfi::{
     crypto::{
         constants::OrchardFixedBases,
         proof::{Proof, ProvingKey, VerifyingKey},
         util::pedersen_commitment_u64,
     },
     serial::Decodable,
-    vm,
+    zk::vm,
 };
 
 fn main() -> std::result::Result<(), failure::Error> {
@@ -26,7 +26,7 @@ fn main() -> std::result::Result<(), failure::Error> {
     let k: u32 = 11;
 
     let start = Instant::now();
-    let file = File::open("proof/mint.zk.bin")?;
+    let file = File::open("../proof/mint.zk.bin")?;
     let zkbin = vm::ZkBinary::decode(file)?;
     for contract_name in zkbin.contracts.keys() {
         println!("Loaded '{}' contract.", contract_name);

+ 3 - 3
src/bin/vm_burn.rs → example/vm_burn.rs

@@ -17,7 +17,7 @@ use pasta_curves::{
 use rand::rngs::OsRng;
 use std::{collections::HashMap, fs::File, time::Instant};
 
-use drk::{
+use darkfi::{
     crypto::{
         constants::{
             sinsemilla::{i2lebsp, MERKLE_CRH_PERSONALIZATION},
@@ -27,7 +27,7 @@ use drk::{
         util::pedersen_commitment_u64,
     },
     serial::Decodable,
-    vm,
+    zk::vm,
 };
 
 fn root(path: [pallas::Base; 32], leaf_pos: u32, leaf: pallas::Base) -> pallas::Base {
@@ -57,7 +57,7 @@ fn main() -> std::result::Result<(), failure::Error> {
     let k: u32 = 11;
 
     let start = Instant::now();
-    let file = File::open("proof/burn.zk.bin")?;
+    let file = File::open("../proof/burn.zk.bin")?;
     let zkbin = vm::ZkBinary::decode(file)?;
     for contract_name in zkbin.contracts.keys() {
         println!("Loaded '{}' contract.", contract_name);

+ 1 - 1
script/run_burn_zk.sh

@@ -2,4 +2,4 @@
 python zkas.py ../proof/burn.zk --bincode
 du -sh ../proof/burn.zk.bin
 python zkas.py ../proof/burn.zk
-cargo run --all-features --release --bin vm_burn
+cargo run --all-features --release --example vm_burn

+ 1 - 1
script/run_mint_zk.sh

@@ -2,4 +2,4 @@
 python zkas.py ../proof/mint.zk --bincode
 du -sh ../proof/mint.zk.bin
 python zkas.py ../proof/mint.zk
-cargo run --all-features --release --bin vm
+cargo run --all-features --release --example vm

+ 0 - 151
src/bin/darkpulse.rs

@@ -1,151 +0,0 @@
-use async_executor::Executor;
-use async_std::sync::{Arc, Mutex};
-use easy_parallel::Parallel;
-use log::*;
-use smol::Unblock;
-
-use drk::{
-    darkpulse::{
-        dbsql, messages, utility, CiphertextHash, CliOption, ControlCommand, MemPool, SlabsManager,
-    },
-    net::P2p,
-    Result,
-};
-
-async fn on_receive_slab(
-    p2p: Arc<P2p>,
-    slab_rx: async_channel::Receiver<CiphertextHash>,
-) -> Result<()> {
-    loop {
-        let slab = slab_rx.recv().await?;
-        p2p.broadcast(messages::InvMessage { slabs_hash: vec![slab] }).await?;
-    }
-}
-
-async fn start(executor: Arc<Executor<'_>>, options: CliOption, db: dbsql::Dbsql) -> Result<()> {
-    let p2p = P2p::new(options.network_settings);
-
-    p2p.clone().start(executor.clone()).await?;
-
-    let p2p_run_task = executor.spawn(p2p.clone().run(executor.clone()));
-
-    let _mem_pool: MemPool = Arc::new(Mutex::new(vec![]));
-
-    // choose a channel
-    if let Some(new_channel) = options.new_channel {
-        info!("channel added with the name {}", new_channel.get_channel_name());
-        db.add_channel(&new_channel).unwrap();
-    }
-    let main_channel = utility::choose_channel(&db, options.channel_name)?;
-    let channels = db.get_channels()?;
-    let username = utility::setup_username(options.username, &db)?;
-
-    let (slab_sx, slab_rx) = async_channel::unbounded::<CiphertextHash>();
-
-    let slabman = SlabsManager::new(db, slab_sx, main_channel.clone()).await;
-
-    let subscribtion = p2p.subscribe_channel().await;
-
-    let executor2 = executor.clone();
-    let setup_channels_task = executor2.clone().spawn(async move {
-        loop {
-            let network_channel = subscribtion.receive().await.unwrap();
-            utility::setup_network_channel(executor2.clone(), network_channel, slabman.clone())
-                .await;
-        }
-    });
-
-    let receive_slab = executor.spawn(on_receive_slab(p2p.clone(), slab_rx.clone()));
-
-    p2p.broadcast(messages::SyncMessage {}).await?;
-
-    let stdin = Unblock::new(std::io::stdin());
-    let mut stdin = futures::io::BufReader::new(stdin);
-
-    loop {
-        println!("[1] Send Message");
-        println!("[2] Send Sync");
-        println!("[3] list available channels");
-        println!("[4] show the channel address");
-        println!("[5] Quit");
-
-        let buf = utility::read_line(&mut stdin).await?;
-
-        match &buf[..] {
-            "1" => {
-                let slab = utility::pack_slab(
-                    &main_channel.get_channel_secret(),
-                    username.clone(),
-                    String::from("Hello"),
-                    ControlCommand::Message,
-                )
-                .await?;
-
-                p2p.broadcast(slab).await?;
-            }
-            "2" => {
-                p2p.broadcast(messages::SyncMessage {}).await?;
-            }
-            "3" => {
-                println!("------------------");
-                println!("Available channels:");
-                for channel in channels.iter() {
-                    println!("- {}", channel.get_channel_name());
-                }
-                println!("NOTE: switch with one of the available channels by using --channel flag");
-                println!("------------------");
-            }
-            "4" => {
-                println!("------------------");
-                println!("Address: {}", main_channel.get_channel_address());
-                println!("------------------");
-            }
-            "5" => break,
-            _ => {}
-        }
-    }
-
-    setup_channels_task.cancel().await;
-    p2p_run_task.cancel().await;
-    receive_slab.cancel().await;
-    Ok(())
-}
-
-pub fn main() -> Result<()> {
-    use simplelog::*;
-
-    let cli_option = CliOption::get()?;
-
-    let debug_level = if cli_option.verbose { LevelFilter::Debug } else { LevelFilter::Off };
-
-    CombinedLogger::init(vec![
-        TermLogger::new(debug_level, Config::default(), TerminalMode::Mixed, ColorChoice::Always),
-        WriteLogger::new(
-            LevelFilter::Debug,
-            Config::default(),
-            std::fs::File::create("/tmp/darkpulsenode.log").unwrap(),
-        ),
-    ])
-    .unwrap();
-
-    let mut db = dbsql::Dbsql::new()?;
-    db.start()?;
-
-    let ex = Arc::new(Executor::new());
-    let (signal, shutdown) = async_channel::unbounded::<()>();
-    let ex2 = ex.clone();
-
-    let (_, result) = Parallel::new()
-        // Run four executor threads.
-        .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv())))
-        // Run the main future on the current thread.
-        .finish(|| {
-            smol::future::block_on(async move {
-                start(ex2, cli_option, db).await?;
-                drop(signal);
-                Ok::<(), drk::Error>(())
-            })
-        });
-
-    result
-}

+ 0 - 0
src/blockchain/mod.rs → src/chain/mod.rs


+ 1 - 1
src/blockchain/rocks.rs → src/chain/rocks.rs

@@ -4,7 +4,7 @@ use async_std::sync::Arc;
 use rocksdb::{ColumnFamily, ColumnFamilyDescriptor, Options, DB};
 
 use crate::{
-    serial::{deserialize, serialize, Decodable, Encodable},
+    util::serial::{deserialize, serialize, Decodable, Encodable},
     Error, Result,
 };
 

+ 1 - 1
src/blockchain/slab.rs → src/chain/slab.rs

@@ -1,5 +1,5 @@
 use crate::{
-    serial::{Decodable, Encodable},
+    util::serial::{Decodable, Encodable},
     Result,
 };
 

+ 1 - 1
src/blockchain/slabstore.rs → src/chain/slabstore.rs

@@ -7,7 +7,7 @@ use super::{
     slab::Slab,
 };
 use crate::{
-    serial::{deserialize, serialize},
+    util::serial::{deserialize, serialize},
     Result,
 };
 

+ 0 - 11
src/cli/cli_config.rs

@@ -10,17 +10,6 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
 
 use crate::{Error, Result};
 
-pub fn load_keypair_to_str(path: PathBuf) -> Result<String> {
-    if Path::new(&path).exists() {
-        let key = fs::read(&path)?;
-        let str_buff = str::from_utf8(&key)?;
-        Ok(str_buff.to_string())
-    } else {
-        println!("Could not parse keypair path");
-        Err(Error::KeypairPathNotFound)
-    }
-}
-
 #[derive(Clone, Default)]
 pub struct Config<T> {
     config: PhantomData<T>,

+ 1 - 0
src/cli/mod.rs

@@ -2,4 +2,5 @@ pub mod cli_config;
 pub mod cli_parser;
 
 pub use cli_config::{CashierdConfig, Config, DarkfidConfig, DrkConfig, GatewaydConfig};
+
 pub use cli_parser::{CliCashierd, CliDarkfid, CliDrk, CliDrkSubCommands, CliGatewayd};

+ 1 - 1
src/crypto/mint_proof.rs

@@ -12,7 +12,6 @@ use pasta_curves::{
 };
 
 use crate::{
-    circuit::mint_contract::MintContract,
     crypto::{
         coin::Coin,
         keypair::PublicKey,
@@ -21,6 +20,7 @@ use crate::{
     },
     serial::{Decodable, Encodable},
     types::{DrkCoinBlind, DrkSerial, DrkTokenId, DrkValue, DrkValueBlind, DrkValueCommit},
+    zk::circuit::mint_contract::MintContract,
     Result,
 };
 

+ 1 - 1
src/crypto/spend_proof.rs

@@ -18,13 +18,13 @@ use super::{
     util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
 };
 use crate::{
-    circuit::spend_contract::SpendContract,
     crypto::{
         keypair::{PublicKey, SecretKey},
         merkle_node::MerkleNode,
     },
     serial::{Decodable, Encodable},
     types::*,
+    zk::circuit::spend_contract::SpendContract,
     Result,
 };
 

+ 0 - 53
src/darkpulse/aes.rs

@@ -1,53 +0,0 @@
-use aes_gcm::{
-    aead::{generic_array::GenericArray, Aead, NewAead},
-    Aes256Gcm,
-};
-
-pub type AesKey = [u8; 32];
-pub type Plaintext = Vec<u8>;
-pub type Ciphertext = Vec<u8>;
-
-pub fn aes_encrypt(
-    shared_secret: &AesKey,
-    nonce: &[u8; 12],
-    plaintext: &[u8],
-) -> Option<Ciphertext> {
-    // Rust is gay, I need to convert to 'GenericArray' whatever the fuck that is...
-    let key = GenericArray::from_slice(&shared_secret[..]);
-    let cipher = Aes256Gcm::new(key);
-
-    let nonce = GenericArray::from_slice(nonce);
-    let ciphertext = cipher.encrypt(nonce, plaintext);
-    ciphertext.ok()
-}
-
-pub fn aes_decrypt(
-    shared_secret: &AesKey,
-    nonce: &[u8; 12],
-    ciphertext: Ciphertext,
-) -> Option<Plaintext> {
-    // Rust is gay, I need to convert to 'GenericArray' whatever the fuck that is...
-    let key = GenericArray::from_slice(&shared_secret[..]);
-    let cipher = Aes256Gcm::new(key);
-
-    let nonce = GenericArray::from_slice(nonce);
-
-    let plaintext = cipher.decrypt(nonce, ciphertext.as_ref());
-    plaintext.ok()
-}
-
-#[test]
-fn test_aes() {
-    let sh_secret = "e02e56a41320d8ebefa946753e9f69587c16d43876cf5bbac86c0ea0e9253d14".as_bytes();
-
-    let mut channel_secret = [0u8; 32];
-    channel_secret.copy_from_slice(&sh_secret[0..32]);
-
-    let nonce = [3; 12];
-
-    let ciphertext = aes_encrypt(&channel_secret, &nonce, b"plaintext message").unwrap();
-
-    let plaintext = aes_decrypt(&channel_secret, &nonce, ciphertext).unwrap();
-    // OK it works!
-    assert_eq!(&plaintext, b"plaintext message");
-}

+ 0 - 89
src/darkpulse/channel.rs

@@ -1,89 +0,0 @@
-use bs58;
-use rand::Rng;
-use sha2::{Digest, Sha256};
-
-use crate::Result;
-
-#[derive(Clone, Debug)]
-pub struct Channel {
-    channel_secret: [u8; 32],
-    channel_name: String,
-    address: String,
-    id: Option<u32>,
-}
-
-impl Channel {
-    pub fn new(
-        channel_name: String,
-        channel_secret: [u8; 32],
-        address: String,
-        id: u32,
-    ) -> Channel {
-        Channel { channel_secret, channel_name, address, id: Some(id) }
-    }
-
-    pub fn gen_new(channel_name: String) -> Channel {
-        let channel_secret = rand::thread_rng().gen::<[u8; 32]>();
-        let address = Self::gen_address(channel_secret);
-        Channel { channel_secret, channel_name, address, id: None }
-    }
-
-    pub fn gen_new_with_addr(channel_name: String, channel_address: String) -> Result<Channel> {
-        let decoded = bs58::decode(channel_address.clone()).into_vec()?;
-        let mut channel_secret: [u8; 32] = [0; 32];
-        channel_secret.copy_from_slice(&decoded[4..36]);
-        Ok(Channel { channel_secret, channel_name, address: channel_address, id: None })
-    }
-
-    pub fn gen_address(channel_secret: [u8; 32]) -> String {
-        let mut hasher = Sha256::new();
-
-        let version: u32 = 1;
-        let mut payload = version.to_be_bytes().to_vec();
-        let mut channel_secret = channel_secret.to_vec();
-        payload.append(&mut channel_secret);
-        hasher.update(payload.clone());
-        let result = hasher.finalize();
-
-        let mut checksum: [u8; 4] = [0; 4];
-        checksum.copy_from_slice(&result[..4]);
-
-        payload.append(&mut checksum.to_vec());
-
-        let encoded = bs58::encode(payload).into_string();
-
-        encoded
-    }
-
-    pub fn get_channel_secret(&self) -> [u8; 32] {
-        self.channel_secret
-    }
-
-    pub fn get_channel_name(&self) -> &String {
-        &self.channel_name
-    }
-
-    pub fn get_channel_id(&self) -> &Option<u32> {
-        &self.id
-    }
-
-    pub fn get_channel_address(&self) -> &String {
-        &self.address
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::Channel;
-    use crate::Result;
-
-    #[test]
-    fn create_channel_form_address() -> Result<()> {
-        let channel = Channel::gen_new(String::from("test"));
-        let channel_address = channel.get_channel_address();
-        let channel2 = Channel::gen_new_with_addr(String::from("test"), channel_address.clone())?;
-        assert_eq!(channel.get_channel_secret(), channel2.get_channel_secret());
-        assert_eq!(channel.get_channel_address(), channel2.get_channel_address());
-        Ok(())
-    }
-}

+ 0 - 176
src/darkpulse/cli_option.rs

@@ -1,176 +0,0 @@
-use std::net::SocketAddr;
-
-use clap::{App, Arg};
-
-use super::Channel;
-use crate::{net::Settings, Result};
-
-pub struct CliOption {
-    pub network_settings: Settings,
-    pub username: Option<String>,
-    pub channel_name: Option<String>,
-    pub new_channel: Option<Channel>,
-    pub verbose: bool,
-    pub log_path: Box<std::path::PathBuf>,
-}
-
-impl CliOption {
-    pub fn get() -> Result<CliOption> {
-        let mat = App::new("DarkPulse")
-            .version("0.0.1")
-            .author("Dark Renaissance Technologies")
-            .about("An anonymous p2p chat application")
-            .arg(
-                Arg::new("accept")
-                    .short('a')
-                    .value_name("ADDRESSES")
-                    .help("accept address")
-                    .long("accept")
-                    .required(true),
-            )
-            .arg(Arg::new("slots").value_name("SLOTS").long("slots").help("Connection slots"))
-            .arg(Arg::new("verbose").takes_value(false).long("verbose").help("increase verbosity"))
-            .arg(
-                Arg::new("connects")
-                    .value_name("MANUAL_CONNECTS")
-                    .multiple_occurrences(true)
-                    .takes_value(true)
-                    .short('c')
-                    .long("connects")
-                    .help("Manual connections"),
-            )
-            .arg(
-                Arg::new("seed")
-                    .value_name("ADDRESSES")
-                    .multiple_occurrences(true)
-                    .takes_value(true)
-                    .short('s')
-                    .long("seed")
-                    .help("Connect to the seed node"),
-            )
-            .arg(
-                Arg::new("log")
-                    .value_name("LOG_PATH")
-                    .takes_value(true)
-                    .long("log")
-                    .help("Log file path"),
-            )
-            .arg(
-                Arg::new("username")
-                    .value_name("USERNAME")
-                    .short('u')
-                    .long("username")
-                    .help("node's username"),
-            )
-            .arg(
-                Arg::new("channel")
-                    .value_name("CHANNEL")
-                    .short('h')
-                    .long("channel")
-                    .help("switch to one of available channels"),
-            )
-            .subcommand(
-                App::new("newchannel")
-                    .about("add new channel")
-                    .arg(
-                        Arg::new("name")
-                            .long("channelname")
-                            .required(true)
-                            .value_name("CHANNELNAME")
-                            .help("name for the new channel"),
-                    )
-                    .arg(
-                        Arg::new("address")
-                            .long("channeladdress")
-                            .required(true)
-                            .value_name("CHANNELADDRESS")
-                            .help("address for the new channel"),
-                    ),
-            )
-            .get_matches();
-
-        let mut accept_addr: Option<SocketAddr> = None;
-        if let Some(addr) = mat.value_of("accept") {
-            accept_addr = Some(addr.parse()?);
-        }
-
-        let mut connection_slots = 0;
-        if let Some(slots) = mat.value_of("slots") {
-            connection_slots = slots.parse()?;
-        };
-
-        let mut seed_addresses: Vec<SocketAddr> = vec![];
-        if let Some(seed_addrs) = mat.values_of("seed") {
-            seed_addresses = Self::collect_addrs(seed_addrs.collect::<Vec<&str>>());
-        };
-
-        let mut manual_connects: Vec<SocketAddr> = vec![];
-        if let Some(man_connects) = mat.values_of("connects") {
-            manual_connects = Self::collect_addrs(man_connects.collect::<Vec<&str>>());
-        };
-
-        let mut username = None;
-
-        if let Some(uname) = mat.value_of("username") {
-            username = Some(String::from(uname));
-        }
-
-        let mut channel_name = None;
-
-        if let Some(chan) = mat.value_of("channel") {
-            channel_name = Some(String::from(chan));
-        }
-
-        let mut new_channel: Option<Channel> = None;
-
-        if let Some(newch) = mat.subcommand_matches("newchannel") {
-            let mut new_channel_name = String::new();
-            let mut new_channel_address = String::new();
-            if let Some(channelname) = newch.value_of("name") {
-                new_channel_name = String::from(channelname);
-            }
-            if let Some(channeladdress) = newch.value_of("address") {
-                new_channel_address = String::from(channeladdress);
-            }
-            new_channel = Some(Channel::gen_new_with_addr(new_channel_name, new_channel_address)?);
-        }
-
-        let verbose = mat.is_present("verbose");
-
-        let log_path = Box::new(
-            if let Some(log_path) = mat.value_of("log") {
-                std::path::Path::new(log_path)
-            } else {
-                std::path::Path::new("/tmp/darkpulsenode.log")
-            }
-            .to_path_buf(),
-        );
-
-        let network_settings = Settings {
-            inbound: accept_addr,
-            outbound_connections: connection_slots,
-            seed_query_timeout_seconds: 8,
-            connect_timeout_seconds: 10,
-            channel_handshake_seconds: 4,
-            channel_heartbeat_seconds: 10,
-            external_addr: accept_addr,
-            peers: manual_connects,
-            seeds: seed_addresses,
-            manual_attempt_limit: 10,
-        };
-
-        Ok(CliOption { network_settings, username, channel_name, new_channel, verbose, log_path })
-    }
-
-    fn collect_addrs(addrs: Vec<&str>) -> Vec<SocketAddr> {
-        let addrs: Vec<SocketAddr> = addrs
-            .iter()
-            .map(|addr| {
-                let addr: SocketAddr = addr.parse().expect("unable to parse on of the addresses");
-                addr
-            })
-            .collect();
-
-        addrs
-    }
-}

+ 0 - 64
src/darkpulse/control_message.rs

@@ -1,64 +0,0 @@
-use std::io;
-
-use crate::{
-    serial::{Decodable, Encodable},
-    Result,
-};
-
-#[derive(Copy, Clone)]
-pub enum ControlCommand {
-    Join = 0,
-    Leave = 1,
-    Message = 2,
-}
-
-pub struct MessagePayload {
-    pub nickname: String,
-    pub text: String,
-    pub timestamp: i64,
-}
-
-pub struct ControlMessage {
-    pub control: ControlCommand,
-    pub payload: MessagePayload,
-}
-
-impl Encodable for MessagePayload {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.nickname.encode(&mut s)?;
-        len += self.text.encode(&mut s)?;
-        len += self.timestamp.encode(&mut s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for MessagePayload {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self {
-            nickname: Decodable::decode(&mut d)?,
-            text: Decodable::decode(&mut d)?,
-            timestamp: Decodable::decode(&mut d)?,
-        })
-    }
-}
-impl Encodable for ControlMessage {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += (self.control as u8).encode(&mut s)?;
-        len += self.payload.encode(&mut s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for ControlMessage {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        let control_code: u8 = Decodable::decode(&mut d)?;
-        let control = match control_code {
-            0 => ControlCommand::Join,
-            1 => ControlCommand::Leave,
-            _ => ControlCommand::Message,
-        };
-        Ok(Self { control, payload: Decodable::decode(&mut d)? })
-    }
-}

+ 0 - 156
src/darkpulse/dbsql.rs

@@ -1,156 +0,0 @@
-use std::{collections::HashMap, convert::TryInto, fs::File, io::prelude::*};
-
-use rusqlite::{params, Connection};
-
-use super::{utility::default_config_dir, Channel, CiphertextHash, SlabMessage};
-use crate::Result;
-
-#[allow(dead_code)]
-#[derive(Debug)]
-pub struct Dbsql {
-    connection: Connection,
-    username: String,
-}
-
-impl Dbsql {
-    pub fn new() -> Result<Dbsql> {
-        let path = default_config_dir()?.join("data.db");
-        let connection = Connection::open(path)?;
-        let username = String::new();
-        Ok(Dbsql { connection, username })
-    }
-
-    pub fn start(&mut self) -> Result<()> {
-        let schemas = Self::read_schemas_from_file("../../sql/darkpulse_schema.sql")?;
-        self.connection.execute_batch(schemas.as_str())?;
-
-        Ok(())
-    }
-
-    pub fn add_slab(&self, slab: &SlabMessage, channel_id: &u32) -> Result<()> {
-        self.connection.execute(
-            "INSERT OR IGNORE INTO slab (nonce, cipher_text, cipher_text_hash, channel_id) VALUES (?1, ?2, ?3, ?4)",
-            params![&slab.nonce[..], &slab.ciphertext[..], &slab.cipher_hash()[..], channel_id],
-        )?;
-        Ok(())
-    }
-
-    pub fn add_username(&self, username: &str) -> Result<()> {
-        self.connection
-            .execute("INSERT OR IGNORE INTO node (username) VALUES (?1)", params![username])?;
-        Ok(())
-    }
-
-    pub fn get_channel_slabs(&self, id: u32) -> Result<HashMap<CiphertextHash, SlabMessage>> {
-        let stmt = format!("SELECT * FROM slab WHERE channel_id={}", id);
-        let mut stmt = self.connection.prepare(&stmt)?;
-
-        let mut slabs: HashMap<CiphertextHash, SlabMessage> = HashMap::new();
-        let slab_iter = stmt.query_map(params![], |row| {
-            let nonce: Vec<u8> = row.get(1)?;
-            let nonce = nonce
-                .as_slice()
-                .try_into()
-                .expect("error when converting vector to slice with size [u8; 12]");
-
-            let ciphertext = row.get(2)?;
-
-            Ok(SlabMessage { nonce, ciphertext })
-        })?;
-
-        for slab in slab_iter {
-            let slab = slab?;
-            slabs.insert(slab.cipher_hash(), slab);
-        }
-        Ok(slabs)
-    }
-
-    pub fn add_channel(&self, channel: &Channel) -> Result<()> {
-        self.connection.execute(
-            "INSERT OR IGNORE INTO channel (channel_name, channel_secret, address) VALUES (?1, ?2, ?3)",
-            params![
-            &channel.get_channel_name(),
-            &channel.get_channel_secret()[..],
-            &channel.get_channel_address()
-            ],
-        )?;
-        Ok(())
-    }
-
-    pub fn delete_channel(&self, channel_name: &str) -> Result<()> {
-        self.connection
-            .execute("DELETE FROM channel WHERE channel_name = (?1)", params![channel_name,])?;
-        Ok(())
-    }
-
-    fn read_schemas_from_file(path: &str) -> Result<String> {
-        let mut file = File::open(path)?;
-        let mut schemas = String::new();
-        file.read_to_string(&mut schemas)?;
-        Ok(schemas)
-    }
-
-    pub fn get_slabs(&mut self) -> Result<HashMap<CiphertextHash, SlabMessage>> {
-        let mut slabs = HashMap::new();
-        let mut stmt = self.connection.prepare("SELECT * FROM slab")?;
-        let slab_iter = stmt.query_map(params![], |row| {
-            let nonce: Vec<u8> = row.get(1)?;
-
-            let nonce: [u8; 12] = nonce
-                .as_slice()
-                .try_into()
-                .expect("error when converting vector to slice with size [u8; 12]");
-
-            let ciphertext = row.get(2)?;
-
-            Ok(SlabMessage { nonce, ciphertext })
-        })?;
-
-        for slab in slab_iter {
-            let slab = slab?;
-            slabs.insert(slab.cipher_hash(), slab);
-        }
-
-        Ok(slabs)
-    }
-
-    pub fn get_channels(&self) -> Result<Vec<Channel>> {
-        let mut channels = Vec::new();
-        let mut stmt = self.connection.prepare("SELECT * FROM channel")?;
-        let channel_iter = stmt.query_map(params![], |row| {
-            let channel_id = row.get(0)?;
-            let channel_name = row.get(1)?;
-            let channel_secret: Vec<u8> = row.get(2)?;
-
-            let channel_secret: [u8; 32] = channel_secret
-                .as_slice()
-                .try_into()
-                .expect("error when converting vector to slice with size [u8; 32]");
-
-            let address = row.get(3)?;
-            Ok(Channel::new(channel_name, channel_secret, address, channel_id))
-        })?;
-
-        for channel in channel_iter {
-            let channel = channel?;
-            channels.push(channel);
-        }
-
-        Ok(channels.clone())
-    }
-
-    pub fn get_username(&self) -> Result<String> {
-        let mut username = String::new();
-        let mut stmt3 = self.connection.prepare("SELECT * FROM node")?;
-        let uname_iter = stmt3.query_map(params![], |row| {
-            let username: String = row.get(1)?;
-            Ok(username)
-        })?;
-
-        for name in uname_iter {
-            username = name?;
-        }
-
-        Ok(username)
-    }
-}

+ 0 - 21
src/darkpulse/mod.rs

@@ -1,21 +0,0 @@
-pub mod aes;
-pub mod channel;
-pub mod cli_option;
-pub mod control_message;
-pub mod dbsql;
-pub mod net;
-pub mod slabs_manager;
-pub mod utility;
-
-use async_std::sync::{Arc, Mutex};
-
-pub type CiphertextHash = [u8; 32];
-pub type MemPool = Arc<Mutex<Vec<(CiphertextHash, net::messages::SlabMessage)>>>;
-
-pub use aes::{aes_decrypt, aes_encrypt, Ciphertext, Plaintext};
-pub use channel::Channel;
-pub use cli_option::CliOption;
-pub use control_message::{ControlCommand, ControlMessage, MessagePayload};
-pub use dbsql::Dbsql;
-pub use net::{messages, messages::SlabMessage, protocol_slab::ProtocolSlab};
-pub use slabs_manager::{SlabsManager, SlabsManagerSafe};

+ 0 - 104
src/darkpulse/net/messages.rs

@@ -1,104 +0,0 @@
-use std::io;
-
-use crate::{
-    darkpulse::Ciphertext,
-    net::messages::Message,
-    serial::{Decodable, Encodable},
-    Result,
-};
-
-#[derive(Clone)]
-pub struct GetSlabsMessage {
-    pub slabs_hash: Vec<[u8; 32]>,
-}
-
-#[derive(Clone)]
-pub struct InvMessage {
-    pub slabs_hash: Vec<[u8; 32]>,
-}
-
-#[derive(Clone)]
-pub struct SlabMessage {
-    pub nonce: [u8; 12],
-    pub ciphertext: Ciphertext,
-}
-
-#[derive(Clone)]
-pub struct SyncMessage {}
-
-impl Message for SlabMessage {
-    fn name() -> &'static str {
-        "slab"
-    }
-}
-
-impl Message for GetSlabsMessage {
-    fn name() -> &'static str {
-        "getslabs"
-    }
-}
-impl Message for InvMessage {
-    fn name() -> &'static str {
-        "inv"
-    }
-}
-impl Message for SyncMessage {
-    fn name() -> &'static str {
-        "sync"
-    }
-}
-
-impl Encodable for GetSlabsMessage {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.slabs_hash.encode(&mut s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for GetSlabsMessage {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self { slabs_hash: Decodable::decode(&mut d)? })
-    }
-}
-
-impl Encodable for SlabMessage {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.nonce.encode(&mut s)?;
-        len += self.ciphertext.encode(&mut s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for SlabMessage {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self { nonce: Decodable::decode(&mut d)?, ciphertext: Decodable::decode(&mut d)? })
-    }
-}
-
-impl Encodable for InvMessage {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.slabs_hash.encode(&mut s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for InvMessage {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self { slabs_hash: Decodable::decode(&mut d)? })
-    }
-}
-
-impl Encodable for SyncMessage {
-    fn encode<S: io::Write>(&self, _s: S) -> Result<usize> {
-        Ok(0)
-    }
-}
-
-impl Decodable for SyncMessage {
-    fn decode<D: io::Read>(_d: D) -> Result<Self> {
-        Ok(Self {})
-    }
-}

+ 0 - 2
src/darkpulse/net/mod.rs

@@ -1,2 +0,0 @@
-pub mod messages;
-pub mod protocol_slab;

+ 0 - 175
src/darkpulse/net/protocol_slab.rs

@@ -1,175 +0,0 @@
-use std::sync::Arc;
-
-use log::*;
-use smol::Executor;
-
-use crate::{
-    darkpulse::{
-        aes_decrypt, messages, CiphertextHash, ControlCommand, ControlMessage, SlabsManagerSafe,
-    },
-    error::Result as NetResult,
-    net::{
-        message_subscriber::MessageSubscription,
-        protocols::{ProtocolJobsManager, ProtocolJobsManagerPtr},
-        ChannelPtr,
-    },
-    serial::deserialize,
-};
-
-pub struct ProtocolSlab {
-    channel: ChannelPtr,
-    slabman: SlabsManagerSafe,
-
-    sync_sub: MessageSubscription<messages::SyncMessage>,
-    inv_sub: MessageSubscription<messages::InvMessage>,
-    get_slabs_sub: MessageSubscription<messages::GetSlabsMessage>,
-    slab_sub: MessageSubscription<messages::SlabMessage>,
-
-    jobsman: ProtocolJobsManagerPtr,
-}
-
-impl ProtocolSlab {
-    pub async fn new(slabman: SlabsManagerSafe, channel: ChannelPtr) -> Arc<Self> {
-        let sync_sub = channel
-            .clone()
-            .subscribe_msg::<messages::SyncMessage>()
-            .await
-            .expect("Missing sync  dispatcher!");
-
-        let inv_sub = channel
-            .clone()
-            .subscribe_msg::<messages::InvMessage>()
-            .await
-            .expect("Missing inv  dispatcher!");
-
-        let get_slabs_sub = channel
-            .clone()
-            .subscribe_msg::<messages::GetSlabsMessage>()
-            .await
-            .expect("Missing getslabs  dispatcher!");
-
-        let slab_sub = channel
-            .clone()
-            .subscribe_msg::<messages::SlabMessage>()
-            .await
-            .expect("Missing slab  dispatcher!");
-
-        Arc::new(Self {
-            channel: channel.clone(),
-            slabman,
-            sync_sub,
-            inv_sub,
-            get_slabs_sub,
-            slab_sub,
-            jobsman: ProtocolJobsManager::new("ProtocolSlab", channel),
-        })
-    }
-
-    pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
-        debug!(target: "net", "ProtocolSlab::start() [START]");
-        self.jobsman.clone().start(executor.clone());
-
-        self.jobsman.clone().spawn(self.clone().handle_receive_sync(), executor.clone()).await;
-        self.jobsman.clone().spawn(self.clone().handle_receive_inv(), executor.clone()).await;
-
-        self.jobsman.clone().spawn(self.clone().handle_receive_get_slabs(), executor.clone()).await;
-        self.jobsman.clone().spawn(self.clone().handle_receive_slab(), executor).await;
-
-        let _ = self.channel.send(messages::SyncMessage {}).await;
-
-        debug!(target: "net", "ProtocolSlab::start() [END]");
-    }
-
-    async fn handle_receive_sync(self: Arc<Self>) -> NetResult<()> {
-        debug!(target: "net", "ProtocolSlab::handle_receive_sync() [START]");
-        loop {
-            let _sync_msg = self.sync_sub.receive().await?;
-            let slab_hashs = self.slabman.lock().await.get_slabs_hash();
-            let inv_msg = messages::InvMessage { slabs_hash: slab_hashs.clone() };
-            self.channel.send(inv_msg).await?;
-            info!("receive sync message!");
-        }
-    }
-
-    async fn handle_receive_inv(self: Arc<Self>) -> NetResult<()> {
-        debug!(target: "net", "ProtocolSlab::handle_receive_inv() [START]");
-        loop {
-            let inv_msg = self.inv_sub.receive().await?;
-            let mut list_of_hash: Vec<CiphertextHash> = vec![];
-            let slabs_hash = self.slabman.lock().await.get_slabs_hash();
-            for slab in inv_msg.slabs_hash.iter() {
-                if !slabs_hash.contains(slab) {
-                    list_of_hash.push(*slab);
-                }
-            }
-            let getslabs_msg = messages::GetSlabsMessage { slabs_hash: list_of_hash };
-            self.channel.send(getslabs_msg).await?;
-            info!("receive inv message!");
-        }
-    }
-
-    async fn handle_receive_get_slabs(self: Arc<Self>) -> NetResult<()> {
-        debug!(target: "net", "ProtocolSlab::handle_receive_get_slabs() [START]");
-        loop {
-            let get_slabs_msg = self.get_slabs_sub.receive().await?;
-            for slab_hash in get_slabs_msg.slabs_hash.iter() {
-                let slabman = self.slabman.lock().await;
-                let slab = slabman.get_slab(slab_hash);
-                if let Some(slab) = slab {
-                    self.channel.send(slab.clone()).await?;
-                }
-            }
-            info!("receive getslabs message!");
-        }
-    }
-
-    async fn handle_receive_slab(self: Arc<Self>) -> NetResult<()> {
-        debug!(target: "net", "ProtocolSlab::handle_receive_slab() [START]");
-        loop {
-            let slab_msg = self.slab_sub.receive().await?;
-            info!("receive slab message!");
-
-            let channels = self.slabman.lock().await.get_channels().unwrap_or_default();
-
-            let slab = messages::SlabMessage {
-                nonce: slab_msg.nonce,
-                ciphertext: slab_msg.ciphertext.clone(),
-            };
-
-            for channel in channels.iter() {
-                if let Some(plaintext) = aes_decrypt(
-                    &channel.get_channel_secret(),
-                    &slab_msg.nonce,
-                    slab_msg.ciphertext.clone(),
-                ) {
-                    self.slabman
-                        .lock()
-                        .await
-                        .add_new_slab(slab.clone())
-                        .await
-                        .expect("error during adding new slab to database");
-
-                    let des_plaintext: ControlMessage = deserialize(&plaintext[..])
-                        .expect("error during deserializing the message");
-
-                    match des_plaintext.control {
-                        ControlCommand::Join => {
-                            info!("{} joined the group", des_plaintext.payload.nickname);
-                        }
-                        ControlCommand::Leave => {
-                            info!("{} left the group", des_plaintext.payload.nickname);
-                        }
-                        ControlCommand::Message => {
-                            info!(
-                                "{} -> {}: {}",
-                                des_plaintext.payload.timestamp,
-                                des_plaintext.payload.nickname,
-                                des_plaintext.payload.text
-                            );
-                        }
-                    }
-                }
-            }
-        }
-    }
-}

+ 0 - 1
src/darkpulse/net/protocols/mod.rs

@@ -1 +0,0 @@
-pub mod protocol_slab;

+ 0 - 119
src/darkpulse/slabs_manager.rs

@@ -1,119 +0,0 @@
-use std::{collections::HashMap, sync::Arc};
-
-use log::*;
-use sha2::{Digest, Sha256};
-
-use super::{aes::Ciphertext, channel::Channel, dbsql, net::messages::SlabMessage, CiphertextHash};
-use crate::Result;
-
-pub fn cipher_hash(ciphertext: Ciphertext) -> CiphertextHash {
-    let mut cipher_hash = [0u8; 32];
-    let mut hasher = Sha256::new();
-    for chunk in ciphertext.chunks(32) {
-        hasher.update(chunk);
-    }
-    cipher_hash.copy_from_slice(&hasher.finalize());
-    cipher_hash
-}
-
-impl SlabMessage {
-    pub fn cipher_hash(&self) -> CiphertextHash {
-        cipher_hash(self.ciphertext.clone())
-    }
-}
-
-pub type SlabsManagerSafe = Arc<async_std::sync::Mutex<SlabsManager>>;
-
-pub struct SlabsManager {
-    slabs: HashMap<CiphertextHash, SlabMessage>,
-    notify_update: async_channel::Sender<CiphertextHash>,
-    main_channel: Channel,
-    db: dbsql::Dbsql,
-}
-
-impl SlabsManager {
-    pub async fn new(
-        db: dbsql::Dbsql,
-        notify_update: async_channel::Sender<CiphertextHash>,
-        main_channel: Channel,
-    ) -> SlabsManagerSafe {
-        let mut slabs: HashMap<CiphertextHash, SlabMessage> = HashMap::new();
-
-        if let Some(channel_id) = main_channel.get_channel_id() {
-            slabs = db.get_channel_slabs(*channel_id).unwrap_or(slabs);
-        }
-
-        Arc::new(async_std::sync::Mutex::new(SlabsManager {
-            slabs,
-            notify_update,
-            main_channel,
-            db,
-        }))
-    }
-
-    pub fn get_slabs_hash(&self) -> Vec<CiphertextHash> {
-        self.slabs.keys().cloned().collect()
-    }
-    pub fn height(&self) -> u32 {
-        self.slabs.len() as u32
-    }
-    pub fn has_cipher_hash(&self, cipher_hash: &CiphertextHash) -> bool {
-        self.slabs.contains_key(cipher_hash)
-    }
-
-    pub async fn add_new_slab(&mut self, slab: SlabMessage) -> Result<()> {
-        info!("received Slab message.");
-        self.slabs.insert(slab.cipher_hash(), slab.clone());
-
-        if let Some(channel_id) = self.main_channel.get_channel_id() {
-            self.db.add_slab(&slab, channel_id)?;
-        }
-
-        self.notify_update.send(slab.cipher_hash()).await?;
-        Ok(())
-    }
-
-    pub fn set_main_channel(&mut self, main_channel: Channel) {
-        self.main_channel = main_channel;
-        self.switch_main_channel();
-    }
-
-    pub fn switch_main_channel(&mut self) {
-        let default_slabs: HashMap<CiphertextHash, SlabMessage> = HashMap::new();
-
-        if let Some(channel_id) = self.main_channel.get_channel_id() {
-            self.slabs = self.db.get_channel_slabs(*channel_id).unwrap_or(default_slabs);
-        }
-    }
-
-    pub fn get_channels(&mut self) -> Result<Vec<Channel>> {
-        self.db.get_channels()
-    }
-
-    pub fn add_new_channel(&mut self, new_channel: &Channel) -> Result<()> {
-        self.db.add_channel(new_channel)?;
-        Ok(())
-    }
-
-    pub fn delete_channel(&mut self, channel_id: &str) -> Result<()> {
-        self.db.delete_channel(channel_id)?;
-        Ok(())
-    }
-
-    pub fn add_username(&mut self, username: &str) -> Result<()> {
-        self.db.add_username(username)?;
-        Ok(())
-    }
-
-    pub fn get_main_channel(&self) -> Channel {
-        self.main_channel.clone()
-    }
-
-    pub fn get_slab(&self, cipher_hash: &CiphertextHash) -> Option<&SlabMessage> {
-        self.slabs.get(cipher_hash)
-    }
-
-    pub fn get_slabs(&self) -> &HashMap<CiphertextHash, SlabMessage> {
-        &self.slabs
-    }
-}

+ 0 - 164
src/darkpulse/utility.rs

@@ -1,164 +0,0 @@
-use std::{
-    fs::OpenOptions,
-    io::prelude::*,
-    net::SocketAddr,
-    path::PathBuf,
-    sync::{atomic::AtomicU64, Arc},
-    time::{SystemTime, UNIX_EPOCH},
-};
-
-use async_executor::Executor;
-use futures::prelude::*;
-use log::*;
-
-use super::{
-    aes_encrypt, messages, Channel, ControlCommand, ControlMessage, Dbsql, MessagePayload,
-    ProtocolSlab, SlabsManagerSafe,
-};
-
-use crate::{
-    net::ChannelPtr,
-    serial::{deserialize, serialize},
-    Result,
-};
-
-pub type AddrsStorage = Arc<async_std::sync::Mutex<Vec<SocketAddr>>>;
-
-pub type Clock = Arc<AtomicU64>;
-
-pub fn get_current_time() -> u64 {
-    let start = SystemTime::now();
-    let since_the_epoch =
-        start.duration_since(UNIX_EPOCH).expect("Incorrect system clock: time went backwards");
-
-    since_the_epoch.as_secs() * 1000 + since_the_epoch.subsec_nanos() as u64 / 1_000_000
-}
-
-pub fn save_to_addrs_store(stored_addrs: &[SocketAddr]) -> Result<()> {
-    let path = default_config_dir()?.join("addrs.add");
-    let mut writer = OpenOptions::new().write(true).create(true).open(path)?;
-    let buffer = serialize(&stored_addrs.to_vec());
-    writer.write_all(&buffer)?;
-    Ok(())
-}
-
-pub fn default_config_dir() -> Result<PathBuf> {
-    let mut path = PathBuf::new();
-
-    if let Some(home_dir) = dirs::home_dir() {
-        path = home_dir;
-    };
-
-    let path = path.join(".darkpulse/");
-    if !path.exists() {
-        match std::fs::create_dir(&path) {
-            Err(err) => {
-                eprintln!("error: Creating config dir: {}", err);
-                std::process::exit(-1);
-            }
-            Ok(()) => (),
-        }
-    }
-
-    Ok(path)
-}
-
-pub fn load_stored_addrs() -> Result<Vec<SocketAddr>> {
-    let path = default_config_dir()?.join("addrs.add");
-    println!("{:?}", path);
-    let mut reader = OpenOptions::new().read(true).write(true).create(true).open(path)?;
-    let mut buffer = Vec::new();
-    reader.read_to_end(&mut buffer)?;
-    if !buffer.is_empty() {
-        let addrs: Vec<SocketAddr> = deserialize(&buffer)?;
-        Ok(addrs)
-    } else {
-        Ok(vec![])
-    }
-}
-
-pub async fn pack_slab(
-    channel_secret: &[u8; 32],
-    username: String,
-    message: String,
-    control_command: ControlCommand,
-) -> Result<messages::SlabMessage> {
-    let nonce: [u8; 12] = rand::random();
-    let timestamp = chrono::offset::Utc::now();
-    let timestamp: i64 = timestamp.timestamp_millis() / 1000;
-
-    let msg_payload = MessagePayload { nickname: username, text: message, timestamp };
-
-    let control_message = ControlMessage { control: control_command, payload: msg_payload };
-
-    let ser_message = serialize(&control_message);
-
-    let ciphertext = aes_encrypt(channel_secret, &nonce, &ser_message[..])
-        .expect("error during encrypting the message");
-
-    let slab = messages::SlabMessage { nonce, ciphertext };
-
-    Ok(slab)
-}
-
-pub fn setup_username(newname: Option<String>, db: &Dbsql) -> Result<String> {
-    let mut _username: String = String::new();
-    match newname {
-        Some(nm) => {
-            _username = nm.clone();
-            db.add_username(&nm).unwrap();
-        }
-        None => {
-            _username = db.get_username()?;
-            if _username.is_empty() {
-                _username = String::from("username");
-            }
-        }
-    }
-    Ok(_username)
-}
-
-pub async fn read_line<R: AsyncBufRead + Unpin>(reader: &mut R) -> Result<String> {
-    let mut buf = String::new();
-    let _ = reader.read_line(&mut buf).await?;
-    Ok(buf.trim().to_string())
-}
-
-pub fn choose_channel(db: &Dbsql, channel_name: Option<String>) -> Result<Channel> {
-    let channels = db.get_channels()?;
-    let mut main_channel = Channel::gen_new(String::from("test_channel"));
-    if !channels.is_empty() {
-        match channel_name {
-            Some(name) => {
-                main_channel = channels
-                    .iter()
-                    .find(|ch| ch.get_channel_name() == &name)
-                    .unwrap_or_else(|| panic!("there is no channel with the name {}: ", name))
-                    .clone();
-            }
-            None => {
-                main_channel = channels.first().unwrap().clone();
-            }
-        }
-    } else {
-        error!("there are no channels available");
-        db.add_channel(&main_channel)?;
-    }
-    Ok(main_channel)
-}
-
-pub async fn setup_network_channel(
-    executor: Arc<Executor<'_>>,
-    channel: ChannelPtr,
-    slabman: SlabsManagerSafe,
-) {
-    let message_subsytem = channel.get_message_subsystem();
-
-    message_subsytem.add_dispatch::<messages::SyncMessage>().await;
-    message_subsytem.add_dispatch::<messages::InvMessage>().await;
-    message_subsytem.add_dispatch::<messages::GetSlabsMessage>().await;
-    message_subsytem.add_dispatch::<messages::SlabMessage>().await;
-
-    let protocol_slab = ProtocolSlab::new(slabman, channel.clone()).await;
-    protocol_slab.clone().start(executor.clone()).await;
-}

+ 16 - 18
src/lib.rs

@@ -1,28 +1,26 @@
-pub mod async_serial;
-pub mod blockchain;
-pub mod circuit;
 pub mod cli;
-pub mod client;
 pub mod crypto;
-pub mod endian;
-pub mod error;
 pub mod net;
-pub mod rpc;
-pub mod serial;
-pub mod service;
-pub mod state;
 pub mod system;
-pub mod tx;
 pub mod types;
-pub mod util;
-pub mod vm;
-pub mod vm_serial;
-pub mod wallet;
+pub mod zk;
+
+#[cfg(feature = "node")]
+pub mod node;
+
+#[cfg(feature = "node")]
+pub mod tx;
 
 #[cfg(feature = "tui")]
 pub mod tui;
 
-#[cfg(feature = "darkpulse")]
-pub mod darkpulse;
+#[cfg(feature = "chain")]
+pub mod chain;
+
+pub mod util;
 
-pub use crate::error::{Error, Result};
+pub use util::{
+    error,
+    error::{Error, Result},
+    serial,
+};

+ 12 - 9
src/client.rs → src/node/client.rs

@@ -6,8 +6,7 @@ use smol::Executor;
 use url::Url;
 
 use crate::{
-    blockchain::{rocks::columns, Rocks, RocksColumn, Slab},
-    circuit::{MintContract, SpendContract},
+    chain::{rocks::columns, Rocks, RocksColumn, Slab},
     crypto::{
         coin::Coin,
         keypair::{Keypair, PublicKey, SecretKey},
@@ -16,16 +15,20 @@ use crate::{
         OwnCoin,
     },
     serial::{Decodable, Encodable},
-    service::GatewayClient,
-    state::{state_transition, State, StateUpdate},
     tx,
     types::DrkTokenId,
     util::Address,
+    zk::circuit::{MintContract, SpendContract},
+    Result,
+};
+
+use super::{
+    service::GatewayClient,
+    state::{state_transition, State, StateUpdate},
     wallet::{
         cashierdb::CashierDbPtr,
         walletdb::{Balances, WalletPtr},
     },
-    Result,
 };
 
 #[derive(Debug, Clone, thiserror::Error)]
@@ -60,14 +63,14 @@ pub enum ClientFailed {
 
 pub type ClientResult<T> = std::result::Result<T, ClientFailed>;
 
-impl From<super::error::Error> for ClientFailed {
-    fn from(err: super::error::Error) -> ClientFailed {
+impl From<crate::error::Error> for ClientFailed {
+    fn from(err: crate::error::Error) -> ClientFailed {
         ClientFailed::ClientError(err.to_string())
     }
 }
 
-impl From<crate::state::VerifyFailed> for ClientFailed {
-    fn from(err: crate::state::VerifyFailed) -> ClientFailed {
+impl From<super::state::VerifyFailed> for ClientFailed {
+    fn from(err: super::state::VerifyFailed) -> ClientFailed {
         ClientFailed::VerifyError(err.to_string())
     }
 }

+ 4 - 0
src/node/mod.rs

@@ -0,0 +1,4 @@
+pub mod client;
+pub mod service;
+pub mod state;
+pub mod wallet;

+ 1 - 1
src/service/gateway.rs → src/node/service/gateway.rs

@@ -10,7 +10,7 @@ use url::Url;
 
 use super::reqrep::{PeerId, Publisher, RepProtocol, Reply, ReqProtocol, Request, Subscriber};
 use crate::{
-    blockchain::{rocks::columns, RocksColumn, Slab, SlabStore},
+    chain::{rocks::columns, RocksColumn, Slab, SlabStore},
     serial::{deserialize, serialize},
     Error, Result,
 };

+ 4 - 0
src/node/service/mod.rs

@@ -0,0 +1,4 @@
+pub mod gateway;
+pub mod reqrep;
+
+pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber};

+ 0 - 0
src/service/reqrep.rs → src/node/service/reqrep.rs


+ 3 - 2
src/state.rs → src/node/state.rs

@@ -2,7 +2,7 @@ use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
 use log::{debug, error};
 
 use crate::{
-    blockchain::{rocks::columns, RocksColumn},
+    chain::{rocks::columns, RocksColumn},
     crypto::{
         coin::Coin,
         keypair::{PublicKey, SecretKey},
@@ -14,10 +14,11 @@ use crate::{
     },
     error,
     tx::Transaction,
-    wallet::walletdb::WalletPtr,
     Result,
 };
 
+use super::wallet::walletdb::WalletPtr;
+
 pub trait ProgramState {
     fn is_valid_cashier_public_key(&self, public: &PublicKey) -> bool;
     fn is_valid_merkle(&self, merkle: &MerkleNode) -> bool;

+ 8 - 7
src/wallet/cashierdb.rs → src/node/wallet/cashierdb.rs

@@ -9,12 +9,13 @@ use sqlx::{
 };
 
 use super::wallet_api::WalletApi;
+
 use crate::{
-    client::ClientFailed,
     crypto::{
         keypair::{Keypair, PublicKey, SecretKey},
         merkle_node::MerkleNode,
     },
+    node::client::ClientFailed,
     types::DrkTokenId,
     util::NetworkName,
     Error, Result,
@@ -49,7 +50,7 @@ pub struct CashierDb {
 impl WalletApi for CashierDb {}
 
 impl CashierDb {
-    pub async fn new(path: &str, password: String) -> Result<CashierDbPtr> {
+    pub async fn new(path: &str, password: &str) -> Result<CashierDbPtr> {
         debug!("new() Constructor called");
         if password.trim().is_empty() {
             error!("Password is empty. You must set a password to use the wallet.");
@@ -65,7 +66,7 @@ impl CashierDb {
         }
 
         let mut connect_opts = SqliteConnectOptions::from_str(path)?
-            .pragma("key", password)
+            .pragma("key", password.to_string())
             .create_if_missing(true)
             .journal_mode(SqliteJournalMode::Off);
 
@@ -79,9 +80,9 @@ impl CashierDb {
     }
 
     pub async fn init_db(&self) -> Result<()> {
-        let main_kps = include_str!("../../sql/cashier_main_keypairs.sql");
-        let deposit_kps = include_str!("../../sql/cashier_deposit_keypairs.sql");
-        let withdraw_kps = include_str!("../../sql/cashier_withdraw_keypairs.sql");
+        let main_kps = include_str!("../../../sql/cashier_main_keypairs.sql");
+        let deposit_kps = include_str!("../../../sql/cashier_deposit_keypairs.sql");
+        let withdraw_kps = include_str!("../../../sql/cashier_withdraw_keypairs.sql");
 
         let mut conn = self.conn.acquire().await?;
 
@@ -486,7 +487,7 @@ mod tests {
 
     #[async_std::test]
     async fn test_cashierdb() -> Result<()> {
-        let wallet = CashierDb::new("sqlite::memory:", WPASS.to_string()).await?;
+        let wallet = CashierDb::new("sqlite::memory:", WPASS).await?;
 
         // init_db()
         wallet.init_db().await?;

+ 0 - 0
src/wallet/mod.rs → src/node/wallet/mod.rs


+ 0 - 0
src/wallet/wallet_api.rs → src/node/wallet/wallet_api.rs


+ 9 - 8
src/wallet/walletdb.rs → src/node/wallet/walletdb.rs

@@ -10,7 +10,6 @@ use sqlx::{
 };
 
 use crate::{
-    client::ClientFailed,
     crypto::{
         coin::Coin,
         keypair::{Keypair, PublicKey, SecretKey},
@@ -19,12 +18,14 @@ use crate::{
         nullifier::Nullifier,
         OwnCoin, OwnCoins,
     },
+    node::client::ClientFailed,
     serial::serialize,
     types::DrkTokenId,
-    wallet::wallet_api::WalletApi,
     Error, Result,
 };
 
+use super::wallet_api::WalletApi;
+
 pub type WalletPtr = Arc<WalletDb>;
 
 #[derive(Clone, Debug)]
@@ -46,7 +47,7 @@ pub struct WalletDb {
 impl WalletApi for WalletDb {}
 
 impl WalletDb {
-    pub async fn new(path: &str, password: String) -> Result<WalletPtr> {
+    pub async fn new(path: &str, password: &str) -> Result<WalletPtr> {
         if password.trim().is_empty() {
             error!("Password is empty. You must set a password to use the wallet.");
             return Err(Error::from(ClientFailed::EmptyPassword))
@@ -61,7 +62,7 @@ impl WalletDb {
         }
 
         let mut connect_opts = SqliteConnectOptions::from_str(path)?
-            .pragma("key", password)
+            .pragma("key", password.to_string())
             .create_if_missing(true)
             .journal_mode(SqliteJournalMode::Off);
 
@@ -76,9 +77,9 @@ impl WalletDb {
 
     pub async fn init_db(&self) -> Result<()> {
         info!("Initializing wallet database");
-        let tree = include_str!("../../sql/tree.sql");
-        let keys = include_str!("../../sql/keys.sql");
-        let coins = include_str!("../../sql/coins.sql");
+        let tree = include_str!("../../../sql/tree.sql");
+        let keys = include_str!("../../../sql/keys.sql");
+        let coins = include_str!("../../../sql/coins.sql");
 
         let mut conn = self.conn.acquire().await?;
 
@@ -404,7 +405,7 @@ mod tests {
 
     #[async_std::test]
     async fn test_walletdb() -> Result<()> {
-        let wallet = WalletDb::new("sqlite::memory:", WPASS.to_string()).await?;
+        let wallet = WalletDb::new("sqlite::memory:", WPASS).await?;
         let keypair = Keypair::random(&mut OsRng);
 
         // init_db()

+ 1 - 1
src/tx/mod.rs

@@ -20,8 +20,8 @@ use crate::{
     },
     error::Result,
     impl_vec,
+    node::state,
     serial::{Decodable, Encodable, VarInt},
-    state,
     types::{DrkTokenId, DrkValueBlind, DrkValueCommit},
 };
 

+ 1 - 1
src/async_serial.rs → src/util/async_serial.rs

@@ -1,6 +1,6 @@
 use futures::prelude::*;
 
-use crate::{endian, serial::VarInt, Error, Result};
+use super::{endian, serial::VarInt, Error, Result};
 
 impl VarInt {
     pub async fn encode_async<W: AsyncWrite + Unpin>(&self, stream: &mut W) -> Result<usize> {

+ 0 - 0
src/endian.rs → src/util/endian.rs


+ 9 - 12
src/error.rs → src/util/error.rs

@@ -1,5 +1,3 @@
-use crate::{client, state};
-
 pub type Result<T> = std::result::Result<T, Error>;
 
 #[derive(Debug, Clone, thiserror::Error)]
@@ -79,8 +77,10 @@ pub enum Error {
     PlonkError(String),
     #[error("Unable to decrypt mint note")]
     NoteDecryptionFailed,
+
+    #[cfg(feature = "node")]
     #[error(transparent)]
-    VerifyFailed(#[from] state::VerifyFailed),
+    VerifyFailed(#[from] crate::node::state::VerifyFailed),
     #[error("MerkleTree is full")]
     TreeFull,
 
@@ -164,18 +164,21 @@ pub enum Error {
     InvalidAddress,
 }
 
+#[cfg(feature = "node")]
 impl From<zeromq::ZmqError> for Error {
     fn from(err: zeromq::ZmqError) -> Error {
         Error::ZmqError(err.to_string())
     }
 }
 
+#[cfg(feature = "chain")]
 impl From<rocksdb::Error> for Error {
     fn from(err: rocksdb::Error) -> Error {
         Error::RocksdbError(err.to_string())
     }
 }
 
+#[cfg(feature = "node")]
 impl From<sqlx::error::Error> for Error {
     fn from(err: sqlx::error::Error) -> Error {
         Error::SqlxError(err.to_string())
@@ -212,8 +215,9 @@ impl From<url::ParseError> for Error {
     }
 }
 
-impl From<client::ClientFailed> for Error {
-    fn from(err: client::ClientFailed) -> Error {
+#[cfg(feature = "node")]
+impl From<crate::node::client::ClientFailed> for Error {
+    fn from(err: crate::node::client::ClientFailed) -> Error {
         Error::ClientFailed(err.to_string())
     }
 }
@@ -243,13 +247,6 @@ impl From<halo2::plonk::Error> for Error {
     }
 }
 
-#[cfg(feature = "darkpulse")]
-impl From<rusqlite::Error> for Error {
-    fn from(err: rusqlite::Error) -> Error {
-        Error::SqlxError(err.to_string())
-    }
-}
-
 impl From<Box<bincode::ErrorKind>> for Error {
     fn from(err: Box<bincode::ErrorKind>) -> Error {
         Error::BincodeError(err.to_string())

+ 3 - 3
src/util/loader.rs

@@ -1,12 +1,12 @@
 use std::{fs::*, path::PathBuf, time::Instant};
 
 use crate::{
-    circuit::MintContract,
     crypto::proof::{ProvingKey, VerifyingKey},
-    serial::Decodable,
-    vm, Result,
+    zk::{circuit::MintContract, vm},
 };
 
+use super::{serial::Decodable, Result};
+
 pub struct ContractLoader {}
 
 impl ContractLoader {

+ 8 - 1
src/util/mod.rs

@@ -1,16 +1,23 @@
 pub mod address;
+pub mod async_serial;
 pub mod async_util;
+pub mod endian;
+pub mod error;
 pub mod loader;
 pub mod net_name;
 pub mod parse;
 pub mod path;
+pub mod rpc;
+pub mod serial;
 pub mod token_list;
 
 pub use async_util::sleep;
 pub use loader::ContractLoader;
 pub use net_name::NetworkName;
 pub use parse::{assign_id, decode_base10, encode_base10, generate_id, generate_id2};
-pub use path::{expand_path, join_config_path};
+pub use path::{expand_path, join_config_path, load_keypair_to_str};
 pub use token_list::{DrkTokenList, TokenList};
 
 pub use address::Address;
+
+pub use error::{Error, Result};

+ 2 - 4
src/util/parse.rs

@@ -10,6 +10,8 @@ use crate::{
     Error, Result,
 };
 
+pub const ETH_NATIVE_TOKEN_ID: &str = "0x0000000000000000000000000000000000000000";
+
 // hash the external token ID and NetworkName param.
 // if fails, change the last 4 bytes and hash it again. keep repeating until it works.
 pub fn generate_id(tkn_str: &str, network: &NetworkName) -> Result<DrkTokenId> {
@@ -81,7 +83,6 @@ pub fn assign_id(
     btc_tokenlist: &TokenList,
 ) -> Result<String> {
     match network {
-        #[cfg(feature = "sol")]
         NetworkName::Solana => {
             // (== 44) can represent a Solana base58 token mint address
             if token.len() == 44 {
@@ -91,7 +92,6 @@ pub fn assign_id(
                 symbol_to_id(&tok_lower, sol_tokenlist)
             }
         }
-        #[cfg(feature = "btc")]
         NetworkName::Bitcoin => {
             if token.len() == 34 {
                 Ok(token.to_string())
@@ -100,9 +100,7 @@ pub fn assign_id(
                 symbol_to_id(&tok_lower, btc_tokenlist)
             }
         }
-        #[cfg(feature = "eth")]
         NetworkName::Ethereum => {
-            use crate::service::eth::ETH_NATIVE_TOKEN_ID;
             // (== 42) can represent a erc20 token mint address
             if token.len() == 42 {
                 Ok(token.to_string())

+ 17 - 2
src/util/path.rs

@@ -1,5 +1,9 @@
-use crate::Result;
-use std::path::{Path, PathBuf};
+use std::{
+    fs,
+    path::{Path, PathBuf},
+};
+
+use crate::{Error, Result};
 
 pub fn expand_path(path: &str) -> Result<PathBuf> {
     let ret: PathBuf;
@@ -30,3 +34,14 @@ pub fn join_config_path(file: &Path) -> Result<PathBuf> {
 
     Ok(path)
 }
+
+pub fn load_keypair_to_str(path: PathBuf) -> Result<String> {
+    if Path::new(&path).exists() {
+        let key = fs::read(&path)?;
+        let str_buff = std::str::from_utf8(&key)?;
+        Ok(str_buff.to_string())
+    } else {
+        println!("Could not parse keypair path");
+        Err(Error::KeypairPathNotFound)
+    }
+}

+ 0 - 0
src/rpc/jsonrpc.rs → src/util/rpc/jsonrpc.rs


+ 0 - 0
src/rpc/mod.rs → src/util/rpc/mod.rs


+ 1 - 1
src/rpc/rpcserver.rs → src/util/rpc/rpcserver.rs

@@ -14,7 +14,7 @@ use smol::{
 };
 
 use crate::{
-    rpc::jsonrpc::{JsonRequest, JsonResult},
+    util::rpc::jsonrpc::{JsonRequest, JsonResult},
     Result,
 };
 

+ 0 - 0
src/rpc/websockets.rs → src/util/rpc/websockets.rs


+ 1 - 1
src/serial.rs → src/util/serial.rs

@@ -8,7 +8,7 @@ use std::{
 
 use num_bigint::BigUint;
 
-use crate::{
+use super::{
     endian,
     error::{Error, Result},
 };

+ 0 - 0
src/circuit/mint_contract.rs → src/zk/circuit/mint_contract.rs


+ 0 - 0
src/circuit/mod.rs → src/zk/circuit/mod.rs


+ 0 - 0
src/circuit/spend_contract.rs → src/zk/circuit/spend_contract.rs


+ 3 - 0
src/zk/mod.rs

@@ -0,0 +1,3 @@
+pub mod circuit;
+pub mod vm;
+pub mod vm_serial;

+ 0 - 0
src/vm.rs → src/zk/vm.rs


+ 1 - 1
src/vm_serial.rs → src/zk/vm_serial.rs

@@ -1,10 +1,10 @@
 use std::io;
 
+use super::vm::{ZkBinary, ZkContract, ZkFunctionCall, ZkType};
 use crate::{
     error::{Error, Result},
     impl_vec,
     serial::{Decodable, Encodable, ReadExt, VarInt},
-    vm::{ZkBinary, ZkContract, ZkFunctionCall, ZkType},
 };
 
 impl_vec!((String, ZkType));

+ 43 - 0
zkas/proofs/voting.zk

@@ -0,0 +1,43 @@
+constant "Vote" {
+	EcFixedPoint VALUE_COMMIT_VALUE,
+	EcFixedPoint VALUE_COMMIT_RANDOM,
+	EcFixedPoint NULLIFIER_K,
+}
+
+contract "Vote" {
+	Base process_id_0,
+	Base process_id_1,
+	Base secret_key,
+	Base vote,
+	Scalar vote_blind,
+	Uint32 leaf_pos,
+	MerklePath path,
+}
+
+circuit "Vote" {
+	# Nullifier hash
+	process_id = poseidon_hash(process_id_0, process_id_1);
+	nullifier = poseidon_hash(secret_key, process_id);
+	constrain_instance(nullifier);
+
+	# Public key derivation and hashing
+	public_key = ec_mul_base(secret_key, NULLIFIER_K);
+	public_x = ec_get_x(public_key);
+	public_y = ec_get_y(public_key);
+	pk_hash = poseidon_hash(public_x, public_y);
+
+	# Merkle root
+	root = calculate_merkle_root(leaf_pos, path, pk_hash);
+	constrain_instance(root);
+
+	# Pedersen commitment for vote
+	vcv = ec_mul_short(vote, VALUE_COMMIT_VALUE);
+	vcr = ec_mul(vote_blind, VALUE_COMMIT_RANDOM);
+	vote_commit = ec_add(vcv, vcr);
+	# Since vote_commit is a curve point, we fetch its coordinates
+	# and constrain_them:
+	vote_commit_x = ec_get_x(vote_commit);
+	vote_commit_y = ec_get_y(vote_commit);
+	constrain_instance(vote_commit_x);
+	constrain_instance(vote_commit_y);
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов