darkfid.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. use drk::blockchain::{rocks::columns, Rocks, RocksColumn};
  2. use drk::cli::{cli_config, WalletCli};
  3. use drk::crypto::{
  4. load_params,
  5. merkle::{CommitmentTree, IncrementalWitness},
  6. merkle_node::MerkleNode,
  7. note::{EncryptedNote, Note},
  8. nullifier::Nullifier,
  9. save_params, setup_mint_prover, setup_spend_prover,
  10. };
  11. use drk::serial::Decodable;
  12. use drk::service::{GatewayClient, GatewaySlabsSubscriber};
  13. use drk::state::{state_transition, ProgramState, StateUpdate};
  14. use drk::util::join_config_path;
  15. use drk::wallet::{WalletDB, WalletPtr};
  16. use drk::{tx, Result};
  17. use log::*;
  18. //use drk::rpc::
  19. use drk::rpc::adapter::RpcAdapter;
  20. use drk::rpc::jsonserver;
  21. use async_executor::Executor;
  22. use bellman::groth16;
  23. use bls12_381::Bls12;
  24. use easy_parallel::Parallel;
  25. use ff::Field;
  26. use rand::rngs::OsRng;
  27. use rusqlite::Connection;
  28. use async_std::sync::Arc;
  29. use std::net::SocketAddr;
  30. use std::path::Path;
  31. use std::path::PathBuf;
  32. #[allow(dead_code)]
  33. pub struct State {
  34. // The entire merkle tree state
  35. tree: CommitmentTree<MerkleNode>,
  36. // List of all previous and the current merkle roots
  37. // This is the hashed value of all the children.
  38. merkle_roots: RocksColumn<columns::MerkleRoots>,
  39. // Nullifiers prevent double spending
  40. nullifiers: RocksColumn<columns::Nullifiers>,
  41. // All received coins
  42. // Mint verifying key used by ZK
  43. mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  44. // Spend verifying key used by ZK
  45. spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  46. // Public key of the cashier
  47. // List of all our secret keys
  48. wallet: WalletPtr,
  49. }
  50. impl ProgramState for State {
  51. fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
  52. let conn = Connection::open(&self.wallet.path).expect("Failed to connect to database");
  53. let mut stmt = conn
  54. .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
  55. .expect("Cannot generate statement.");
  56. stmt.exists([1i32]).expect("Failed to read database")
  57. // do actual validity check
  58. }
  59. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  60. self.merkle_roots
  61. .key_exist(*merkle_root)
  62. .expect("couldn't check if the merkle_root valid")
  63. }
  64. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  65. self.nullifiers
  66. .key_exist(nullifier.repr)
  67. .expect("couldn't check if nullifier exists")
  68. }
  69. // load from disk
  70. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  71. &self.mint_pvk
  72. }
  73. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  74. &self.spend_pvk
  75. }
  76. }
  77. impl State {
  78. async fn apply(&mut self, update: StateUpdate) -> Result<()> {
  79. // Extend our list of nullifiers with the ones from the update
  80. for nullifier in update.nullifiers {
  81. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  82. }
  83. // Update merkle tree and witnesses
  84. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  85. // Add the new coins to the merkle tree
  86. let node = MerkleNode::from_coin(&coin);
  87. self.tree.append(node).expect("Append to merkle tree");
  88. // Keep track of all merkle roots that have existed
  89. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  90. // Also update all the coin witnesses
  91. for witness in self.wallet.witnesses.lock().await.iter_mut() {
  92. witness.append(node).expect("append to witness");
  93. }
  94. if let Some((note, secret)) = self.try_decrypt_note(enc_note).await {
  95. // We need to keep track of the witness for this coin.
  96. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  97. // Just as we update the merkle tree with every new coin, so we do the same with
  98. // the witness.
  99. // Derive the current witness from the current tree.
  100. // This is done right after we add our coin to the tree (but before any other
  101. // coins are added)
  102. // Make a new witness for this coin
  103. let witness = IncrementalWitness::from_tree(&self.tree);
  104. self.wallet
  105. .put_own_coins(coin, note, witness, secret)
  106. .await?;
  107. }
  108. }
  109. Ok(())
  110. }
  111. async fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, jubjub::Fr)> {
  112. let vec = self.wallet.get_private().ok()?;
  113. let secret = self
  114. .wallet
  115. .get_value_deserialized::<jubjub::Fr>(vec)
  116. .await
  117. .expect("Deserialize failed");
  118. match ciphertext.decrypt(&secret) {
  119. Ok(note) => {
  120. // ... and return the decrypted note for this coin.
  121. return Some((note, secret.clone()));
  122. }
  123. Err(_) => {}
  124. }
  125. // We weren't able to decrypt the note with our key.
  126. None
  127. }
  128. }
  129. pub async fn subscribe(gateway_slabs_sub: GatewaySlabsSubscriber, mut state: State) -> Result<()> {
  130. loop {
  131. let slab = gateway_slabs_sub.recv().await?;
  132. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  133. let update = state_transition(&state, tx)?;
  134. state.apply(update).await?;
  135. }
  136. }
  137. async fn start(
  138. executor: Arc<Executor<'_>>,
  139. config: Arc<cli_config::Config>,
  140. _options: Arc<WalletCli>,
  141. ) -> Result<()> {
  142. let connect_addr: SocketAddr = config.connect_url.parse()?;
  143. let sub_addr: SocketAddr = config.subscriber_url.parse()?;
  144. let database_path = config.database_path.clone();
  145. let database_path = join_config_path(&PathBuf::from(database_path))?;
  146. let rocks = Rocks::new(&database_path)?;
  147. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  148. // Auto create trusted ceremony parameters if they don't exist
  149. if !Path::new("mint.params").exists() {
  150. let params = setup_mint_prover();
  151. save_params("mint.params", &params)?;
  152. }
  153. if !Path::new("spend.params").exists() {
  154. let params = setup_spend_prover();
  155. save_params("spend.params", &params)?;
  156. }
  157. // Load trusted setup parameters
  158. let (_mint_params, mint_pvk) = load_params("mint.params")?;
  159. let (_spend_params, spend_pvk) = load_params("spend.params")?;
  160. //let cashier_secret = jubjub::Fr::random(&mut OsRng);
  161. //let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
  162. // wallet secret key
  163. let secret = jubjub::Fr::random(&mut OsRng);
  164. // wallet public key
  165. let _public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  166. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  167. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  168. let wallet = Arc::new(WalletDB::new("wallet.db")?);
  169. let ex = executor.clone();
  170. let adapter = RpcAdapter::new(wallet.clone())?;
  171. // start the rpc server
  172. jsonserver::start(ex.clone(), config.clone(), adapter).await?;
  173. let state = State {
  174. tree: CommitmentTree::empty(),
  175. merkle_roots,
  176. nullifiers,
  177. mint_pvk,
  178. spend_pvk,
  179. wallet: wallet.clone(),
  180. };
  181. // create gateway client
  182. debug!(target: "Client", "Creating client");
  183. let mut client = GatewayClient::new(connect_addr, slabstore)?;
  184. debug!(target: "Gateway", "Start subscriber");
  185. // start subscribing
  186. let gateway_slabs_sub: GatewaySlabsSubscriber =
  187. client.start_subscriber(sub_addr, executor.clone()).await?;
  188. let subscribe_task = executor.spawn(subscribe(gateway_slabs_sub, state));
  189. // start gateway client
  190. debug!(target: "fn::start client", "start() Client started");
  191. client.start().await?;
  192. subscribe_task.cancel().await;
  193. Ok(())
  194. }
  195. fn main() -> Result<()> {
  196. use simplelog::*;
  197. let mut config = cli_config::Config::load(PathBuf::from("darkfid_config_file"))?;
  198. let options = Arc::new(WalletCli::load(&mut config)?);
  199. if options.change_config {
  200. config.save(PathBuf::from("darkfid_config_file"))?;
  201. std::process::exit(-1);
  202. }
  203. let config = Arc::new(config);
  204. let ex = Arc::new(Executor::new());
  205. let (signal, shutdown) = async_channel::unbounded::<()>();
  206. let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
  207. let debug_level = if options.verbose {
  208. LevelFilter::Debug
  209. } else {
  210. LevelFilter::Off
  211. };
  212. let log_path = config.log_path.clone();
  213. CombinedLogger::init(vec![
  214. TermLogger::new(debug_level, logger_config, TerminalMode::Mixed).unwrap(),
  215. WriteLogger::new(
  216. LevelFilter::Debug,
  217. Config::default(),
  218. std::fs::File::create(log_path).unwrap(),
  219. ),
  220. ])
  221. .unwrap();
  222. let ex2 = ex.clone();
  223. let (_, result) = Parallel::new()
  224. // Run four executor threads.
  225. .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv())))
  226. // Run the main future on the current thread.
  227. .finish(|| {
  228. smol::future::block_on(async move {
  229. start(ex2, config, options).await?;
  230. drop(signal);
  231. Ok::<(), drk::Error>(())
  232. })
  233. });
  234. result
  235. }
  236. //// $ cargo test test_ten_clients_simultaneously --bin darkfid
  237. //this will run 10 clients simultaneously
  238. //// $ cargo test test_subscriber --bin darkfid
  239. // Run Client A and send 10 slabs
  240. // Client B should receive 10 slabs from subscriber
  241. //// $ cargo test test_deposit --bin darkfid
  242. // Run Client A and send 10 slabs
  243. // Client B should receive 10 slabs from subscriber
  244. #[cfg(test)]
  245. mod test {
  246. use std::net::SocketAddr;
  247. use std::path::Path;
  248. use std::path::PathBuf;
  249. use std::sync::Arc;
  250. use drk::blockchain::{rocks::columns, Rocks, RocksColumn, Slab};
  251. use drk::service::{GatewayClient, GatewaySlabsSubscriber};
  252. use drk::util::join_config_path;
  253. use async_executor::Executor;
  254. use easy_parallel::Parallel;
  255. use log::*;
  256. use rand::Rng;
  257. use simplelog::*;
  258. pub async fn subscribe(gateway_slabs_sub: GatewaySlabsSubscriber, id: String) {
  259. loop {
  260. gateway_slabs_sub.recv().await.unwrap();
  261. info!("Client {}: update state", id);
  262. }
  263. }
  264. fn setup_log() {
  265. let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
  266. CombinedLogger::init(vec![
  267. TermLogger::new(LevelFilter::Debug, logger_config, TerminalMode::Mixed).unwrap(),
  268. WriteLogger::new(
  269. LevelFilter::Debug,
  270. Config::default(),
  271. std::fs::File::create(Path::new("/tmp/dar.log")).unwrap(),
  272. ),
  273. ])
  274. .unwrap();
  275. }
  276. #[test]
  277. fn test_ten_clients_simultaneously() {
  278. setup_log();
  279. let mut thread_pools: Vec<std::thread::JoinHandle<()>> = vec![];
  280. for _ in 0..10 {
  281. let thread = std::thread::spawn(|| {
  282. let ex = Arc::new(Executor::new());
  283. let (signal, shutdown) = async_channel::unbounded::<()>();
  284. let ex2 = ex.clone();
  285. let (_, _) = Parallel::new()
  286. // Run four executor threads.
  287. .each(0..3, |_| smol::future::block_on(ex2.run(shutdown.recv())))
  288. // Run the main future on the current thread.
  289. .finish(|| {
  290. smol::future::block_on(async move {
  291. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  292. let sub_addr: SocketAddr = "127.0.0.1:4444".parse().unwrap();
  293. let mut rng = rand::thread_rng();
  294. let rnd: u32 = rng.gen();
  295. let path_str = format!("database_{}.db", rnd);
  296. let database_path = PathBuf::from(path_str.as_str());
  297. let database_path = join_config_path(&database_path).unwrap();
  298. let rocks = Rocks::new(&database_path).unwrap();
  299. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  300. // create gateway client
  301. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  302. // start subscribing
  303. let gateway_slabs_sub: GatewaySlabsSubscriber =
  304. client.start_subscriber(sub_addr, ex.clone()).await.unwrap();
  305. ex.clone()
  306. .spawn(subscribe(gateway_slabs_sub, rnd.clone().to_string()))
  307. .detach();
  308. // start gateway client
  309. client.start().await.unwrap();
  310. let slab = Slab::new(rnd.to_le_bytes().to_vec());
  311. client.put_slab(slab).await.unwrap();
  312. });
  313. drop(signal);
  314. Ok::<(), drk::Error>(())
  315. });
  316. });
  317. thread_pools.push(thread);
  318. }
  319. for t in thread_pools {
  320. t.join().unwrap();
  321. }
  322. }
  323. #[test]
  324. fn test_subscriber() {
  325. setup_log();
  326. let mut thread_pools: Vec<std::thread::JoinHandle<()>> = vec![];
  327. // Client A
  328. let thread = std::thread::spawn(|| {
  329. smol::future::block_on(async move {
  330. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  331. let mut rng = rand::thread_rng();
  332. let rnd: u32 = rng.gen();
  333. let path_str = format!("database_{}.db", rnd);
  334. let database_path = PathBuf::from(path_str.as_str());
  335. let database_path = join_config_path(&database_path).unwrap();
  336. let rocks = Rocks::new(&database_path).unwrap();
  337. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  338. // create gateway client
  339. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  340. // start gateway client
  341. client.start().await.unwrap();
  342. let slab = Slab::new(rnd.to_le_bytes().to_vec());
  343. client.put_slab(slab.clone()).await.unwrap();
  344. client.put_slab(slab.clone()).await.unwrap();
  345. client.put_slab(slab.clone()).await.unwrap();
  346. client.put_slab(slab.clone()).await.unwrap();
  347. client.put_slab(slab.clone()).await.unwrap();
  348. client.put_slab(slab.clone()).await.unwrap();
  349. client.put_slab(slab.clone()).await.unwrap();
  350. client.put_slab(slab.clone()).await.unwrap();
  351. client.put_slab(slab.clone()).await.unwrap();
  352. client.put_slab(slab.clone()).await.unwrap();
  353. });
  354. });
  355. // Client B
  356. let thread2 = std::thread::spawn(|| {
  357. let ex = Arc::new(Executor::new());
  358. let (signal, shutdown) = async_channel::unbounded::<()>();
  359. let ex2 = ex.clone();
  360. let (_, _) = Parallel::new()
  361. // Run four executor threads.
  362. .each(0..3, |_| smol::future::block_on(ex2.run(shutdown.recv())))
  363. // Run the main future on the current thread.
  364. .finish(|| {
  365. smol::future::block_on(async move {
  366. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  367. let sub_addr: SocketAddr = "127.0.0.1:4444".parse().unwrap();
  368. let mut rng = rand::thread_rng();
  369. let rnd: u32 = rng.gen();
  370. let path_str = format!("database_{}.db", rnd);
  371. let database_path = PathBuf::from(path_str.as_str());
  372. let database_path = join_config_path(&database_path).unwrap();
  373. let rocks = Rocks::new(&database_path).unwrap();
  374. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  375. // create gateway client
  376. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  377. // start subscribing
  378. let gateway_slabs_sub: GatewaySlabsSubscriber =
  379. client.start_subscriber(sub_addr, ex.clone()).await.unwrap();
  380. ex.clone()
  381. .spawn(subscribe(gateway_slabs_sub, "B".to_string()))
  382. .detach();
  383. // start gateway client
  384. client.start().await.unwrap();
  385. // sleep for 2 seconds
  386. std::thread::sleep(std::time::Duration::from_secs(2));
  387. });
  388. drop(signal);
  389. Ok::<(), drk::Error>(())
  390. });
  391. });
  392. thread_pools.push(thread);
  393. thread_pools.push(thread2);
  394. for t in thread_pools {
  395. t.join().unwrap();
  396. }
  397. }
  398. #[test]
  399. fn test_deposit() {
  400. setup_log();
  401. let mut thread_pools: Vec<std::thread::JoinHandle<()>> = vec![];
  402. // Client A: User
  403. let thread = std::thread::spawn(|| {
  404. smol::future::block_on(async move {
  405. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  406. let mut rng = rand::thread_rng();
  407. let rnd: u32 = rng.gen();
  408. let path_str = format!("database_{}.db", rnd);
  409. let database_path = PathBuf::from(path_str.as_str());
  410. let database_path = join_config_path(&database_path).unwrap();
  411. let rocks = Rocks::new(&database_path).unwrap();
  412. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  413. // create gateway client
  414. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  415. // start gateway client
  416. client.start().await.unwrap();
  417. let slab = Slab::new(rnd.to_le_bytes().to_vec());
  418. client.put_slab(slab.clone()).await.unwrap();
  419. client.put_slab(slab.clone()).await.unwrap();
  420. client.put_slab(slab.clone()).await.unwrap();
  421. client.put_slab(slab.clone()).await.unwrap();
  422. client.put_slab(slab.clone()).await.unwrap();
  423. client.put_slab(slab.clone()).await.unwrap();
  424. client.put_slab(slab.clone()).await.unwrap();
  425. client.put_slab(slab.clone()).await.unwrap();
  426. client.put_slab(slab.clone()).await.unwrap();
  427. client.put_slab(slab.clone()).await.unwrap();
  428. });
  429. });
  430. // Client B: Cashier
  431. let thread2 = std::thread::spawn(|| {
  432. let ex = Arc::new(Executor::new());
  433. let (signal, shutdown) = async_channel::unbounded::<()>();
  434. let ex2 = ex.clone();
  435. let (_, _) = Parallel::new()
  436. // Run four executor threads.
  437. .each(0..3, |_| smol::future::block_on(ex2.run(shutdown.recv())))
  438. // Run the main future on the current thread.
  439. .finish(|| {
  440. smol::future::block_on(async move {
  441. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  442. let sub_addr: SocketAddr = "127.0.0.1:4444".parse().unwrap();
  443. let mut rng = rand::thread_rng();
  444. let rnd: u32 = rng.gen();
  445. let path_str = format!("database_{}.db", rnd);
  446. let database_path = PathBuf::from(path_str.as_str());
  447. let database_path = join_config_path(&database_path).unwrap();
  448. let rocks = Rocks::new(&database_path).unwrap();
  449. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  450. // create gateway client
  451. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  452. // start subscribing
  453. let gateway_slabs_sub: GatewaySlabsSubscriber =
  454. client.start_subscriber(sub_addr, ex.clone()).await.unwrap();
  455. ex.clone()
  456. .spawn(subscribe(gateway_slabs_sub, "B".to_string()))
  457. .detach();
  458. // start gateway client
  459. client.start().await.unwrap();
  460. // sleep for 2 seconds
  461. std::thread::sleep(std::time::Duration::from_secs(2));
  462. });
  463. drop(signal);
  464. Ok::<(), drk::Error>(())
  465. });
  466. });
  467. thread_pools.push(thread);
  468. thread_pools.push(thread2);
  469. for t in thread_pools {
  470. t.join().unwrap();
  471. }
  472. }
  473. }