darkfid.rs 21 KB

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