darkfid.rs 21 KB

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