darkfid.rs 22 KB

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