darkfid.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. use async_std::sync::Arc;
  2. use rand::rngs::OsRng;
  3. use std::net::SocketAddr;
  4. use drk::blockchain::{rocks::columns, Rocks, RocksColumn};
  5. use drk::crypto::{
  6. coin::Coin,
  7. load_params,
  8. merkle::{CommitmentTree, IncrementalWitness},
  9. merkle_node::MerkleNode,
  10. note::{EncryptedNote, Note},
  11. nullifier::Nullifier,
  12. save_params, setup_mint_prover, setup_spend_prover,
  13. };
  14. use drk::serial::Decodable;
  15. use drk::service::{ClientProgramOptions, GatewayClient, GatewaySlabsSubscriber};
  16. use drk::state::{state_transition, ProgramState, StateUpdate};
  17. use drk::wallet::WalletDB;
  18. use drk::{tx, Result};
  19. use rusqlite::Connection;
  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 std::path::Path;
  26. pub struct State {
  27. // The entire merkle tree state
  28. tree: CommitmentTree<MerkleNode>,
  29. // List of all previous and the current merkle roots
  30. // This is the hashed value of all the children.
  31. merkle_roots: RocksColumn<columns::MerkleRoots>,
  32. // Nullifiers prevent double spending
  33. nullifiers: RocksColumn<columns::Nullifiers>,
  34. // All received coins
  35. own_coins: Vec<(Coin, Note, jubjub::Fr, IncrementalWitness<MerkleNode>)>,
  36. // Mint verifying key used by ZK
  37. mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  38. // Spend verifying key used by ZK
  39. spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  40. // Public key of the cashier
  41. cashier_public: jubjub::SubgroupPoint,
  42. // List of all our secret keys
  43. secrets: Vec<jubjub::Fr>,
  44. }
  45. impl ProgramState for State {
  46. fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
  47. // Still needs to be tested
  48. let path = WalletDB::path("cashier.db").expect("Failed to get path");
  49. let connect = Connection::open(&path).expect("Failed to connect to database.");
  50. let mut stmt = connect
  51. .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
  52. .expect("Cannot generate statement.");
  53. stmt.exists([1i32]).unwrap()
  54. }
  55. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  56. self.merkle_roots
  57. .key_exist(*merkle_root)
  58. .expect("couldn't check if the merkle_root valid")
  59. }
  60. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  61. self.nullifiers
  62. .key_exist(nullifier.repr)
  63. .expect("couldn't check if nullifier exists")
  64. }
  65. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  66. &self.mint_pvk
  67. }
  68. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  69. &self.spend_pvk
  70. }
  71. }
  72. impl State {
  73. fn apply(&mut self, update: StateUpdate) -> Result<()> {
  74. // Extend our list of nullifiers with the ones from the update
  75. for nullifier in update.nullifiers {
  76. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  77. }
  78. // Update merkle tree and witnesses
  79. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  80. // Add the new coins to the merkle tree
  81. let node = MerkleNode::from_coin(&coin);
  82. self.tree.append(node).expect("Append to merkle tree");
  83. // Keep track of all merkle roots that have existed
  84. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  85. // own coins is sql
  86. // Also update all the coin witnesses
  87. for (_, _, _, witness) in self.own_coins.iter_mut() {
  88. witness.append(node).expect("append to witness");
  89. }
  90. if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
  91. // We need to keep track of the witness for this coin.
  92. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  93. // Just as we update the merkle tree with every new coin, so we do the same with
  94. // the witness.
  95. // Derive the current witness from the current tree.
  96. // This is done right after we add our coin to the tree (but before any other
  97. // coins are added)
  98. // Make a new witness for this coin
  99. let witness = IncrementalWitness::from_tree(&self.tree);
  100. self.own_coins.push((coin, note, secret, witness));
  101. }
  102. }
  103. Ok(())
  104. }
  105. // sql
  106. fn try_decrypt_note(&self, _ciphertext: EncryptedNote) -> Option<(Note, jubjub::Fr)> {
  107. // TODO
  108. None
  109. }
  110. }
  111. fn setup_addr(address: Option<SocketAddr>, default: SocketAddr) -> SocketAddr {
  112. match address {
  113. Some(addr) => addr,
  114. None => default,
  115. }
  116. }
  117. pub async fn subscribe(gateway_slabs_sub: GatewaySlabsSubscriber, mut state: State) -> Result<()> {
  118. loop {
  119. let slab = gateway_slabs_sub.recv().await?;
  120. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  121. let update = state_transition(&state, tx)?;
  122. state.apply(update)?;
  123. }
  124. }
  125. async fn start(executor: Arc<Executor<'_>>, options: ClientProgramOptions) -> Result<()> {
  126. let connect_addr: SocketAddr = setup_addr(options.connect_addr, "127.0.0.1:3333".parse()?);
  127. let sub_addr: SocketAddr = setup_addr(options.sub_addr, "127.0.0.1:4444".parse()?);
  128. let database_path = options.database_path.as_path();
  129. let rocks = Rocks::new(database_path)?;
  130. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  131. //
  132. // Auto create trusted ceremony parameters if they don't exist
  133. if !Path::new("mint.params").exists() {
  134. let params = setup_mint_prover();
  135. save_params("mint.params", &params)?;
  136. }
  137. if !Path::new("spend.params").exists() {
  138. let params = setup_spend_prover();
  139. save_params("spend.params", &params)?;
  140. }
  141. // Load trusted setup parameters
  142. let (_mint_params, mint_pvk) = load_params("mint.params")?;
  143. let (_spend_params, spend_pvk) = load_params("spend.params")?;
  144. let cashier_secret = jubjub::Fr::random(&mut OsRng);
  145. let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
  146. // wallet secret key
  147. let secret = jubjub::Fr::random(&mut OsRng);
  148. // wallet public key
  149. let _public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  150. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  151. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  152. let state = State {
  153. tree: CommitmentTree::empty(),
  154. merkle_roots,
  155. nullifiers,
  156. own_coins: vec![],
  157. mint_pvk,
  158. spend_pvk,
  159. cashier_public,
  160. secrets: vec![secret.clone()],
  161. };
  162. // create gateway client
  163. let mut client = GatewayClient::new(connect_addr, slabstore)?;
  164. // start subscribing
  165. let gateway_slabs_sub: GatewaySlabsSubscriber =
  166. client.start_subscriber(sub_addr, executor.clone()).await?;
  167. let subscribe_task = executor.spawn(subscribe(gateway_slabs_sub, state));
  168. // start gateway client
  169. client.start().await?;
  170. subscribe_task.cancel().await;
  171. Ok(())
  172. }
  173. fn main() -> Result<()> {
  174. use simplelog::*;
  175. let ex = Arc::new(Executor::new());
  176. let (signal, shutdown) = async_channel::unbounded::<()>();
  177. let options = ClientProgramOptions::load()?;
  178. let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
  179. let debug_level = if options.verbose {
  180. LevelFilter::Debug
  181. } else {
  182. LevelFilter::Off
  183. };
  184. CombinedLogger::init(vec![
  185. TermLogger::new(debug_level, logger_config, TerminalMode::Mixed).unwrap(),
  186. WriteLogger::new(
  187. LevelFilter::Debug,
  188. Config::default(),
  189. std::fs::File::create(options.log_path.as_path()).unwrap(),
  190. ),
  191. ])
  192. .unwrap();
  193. let ex2 = ex.clone();
  194. let (_, result) = Parallel::new()
  195. // Run four executor threads.
  196. .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv())))
  197. // Run the main future on the current thread.
  198. .finish(|| {
  199. smol::future::block_on(async move {
  200. start(ex2, options).await?;
  201. drop(signal);
  202. Ok::<(), drk::Error>(())
  203. })
  204. });
  205. result
  206. }
  207. //// $ cargo test test_ten_clients_simultaneously --bin darkfid
  208. //this will run 10 clients simultaneously
  209. //// $ cargo test test_subscriber --bin darkfid
  210. // Run Client A and send 10 slabs
  211. // Client B should receive 10 slabs from subscriber
  212. #[cfg(test)]
  213. mod test {
  214. use std::net::SocketAddr;
  215. use std::path::Path;
  216. use std::sync::Arc;
  217. use drk::blockchain::{rocks::columns, Rocks, RocksColumn, Slab};
  218. use drk::service::{GatewayClient, GatewaySlabsSubscriber};
  219. use async_executor::Executor;
  220. use easy_parallel::Parallel;
  221. use log::*;
  222. use rand::Rng;
  223. use simplelog::*;
  224. pub async fn subscribe(gateway_slabs_sub: GatewaySlabsSubscriber, id: String) {
  225. loop {
  226. gateway_slabs_sub.recv().await.unwrap();
  227. info!("Client {}: update state", id);
  228. }
  229. }
  230. fn setup_log() {
  231. let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
  232. CombinedLogger::init(vec![
  233. TermLogger::new(LevelFilter::Debug, logger_config, TerminalMode::Mixed).unwrap(),
  234. WriteLogger::new(
  235. LevelFilter::Debug,
  236. Config::default(),
  237. std::fs::File::create(Path::new("/tmp/dar.log")).unwrap(),
  238. ),
  239. ])
  240. .unwrap();
  241. }
  242. #[test]
  243. fn test_ten_clients_simultaneously() {
  244. setup_log();
  245. let mut thread_pools: Vec<std::thread::JoinHandle<()>> = vec![];
  246. for _ in 0..10 {
  247. let thread = std::thread::spawn(|| {
  248. let ex = Arc::new(Executor::new());
  249. let (signal, shutdown) = async_channel::unbounded::<()>();
  250. let ex2 = ex.clone();
  251. let (_, _) = Parallel::new()
  252. // Run four executor threads.
  253. .each(0..3, |_| smol::future::block_on(ex2.run(shutdown.recv())))
  254. // Run the main future on the current thread.
  255. .finish(|| {
  256. smol::future::block_on(async move {
  257. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  258. let sub_addr: SocketAddr = "127.0.0.1:4444".parse().unwrap();
  259. let mut rng = rand::thread_rng();
  260. let rnd: u32 = rng.gen();
  261. let path_str = format!("database_{}.db", rnd);
  262. let database_path = Path::new(path_str.as_str());
  263. let rocks = Rocks::new(database_path.clone()).unwrap();
  264. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  265. // create gateway client
  266. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  267. // start subscribing
  268. let gateway_slabs_sub: GatewaySlabsSubscriber =
  269. client.start_subscriber(sub_addr, ex.clone()).await.unwrap();
  270. ex.clone()
  271. .spawn(subscribe(gateway_slabs_sub, rnd.clone().to_string()))
  272. .detach();
  273. // start gateway client
  274. client.start().await.unwrap();
  275. let slab = Slab::new("btc".to_string(), rnd.to_le_bytes().to_vec());
  276. client.put_slab(slab).await.unwrap();
  277. });
  278. drop(signal);
  279. Ok::<(), drk::Error>(())
  280. });
  281. });
  282. thread_pools.push(thread);
  283. }
  284. for t in thread_pools {
  285. t.join().unwrap();
  286. }
  287. }
  288. #[test]
  289. fn test_subscriber() {
  290. setup_log();
  291. let mut thread_pools: Vec<std::thread::JoinHandle<()>> = vec![];
  292. // Client A
  293. let thread = std::thread::spawn(|| {
  294. smol::future::block_on(async move {
  295. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  296. let mut rng = rand::thread_rng();
  297. let rnd: u32 = rng.gen();
  298. let path_str = format!("database_{}.db", rnd);
  299. let database_path = Path::new(path_str.as_str());
  300. let rocks = Rocks::new(database_path.clone()).unwrap();
  301. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  302. // create gateway client
  303. let mut client = GatewayClient::new(connect_addr, slabstore).unwrap();
  304. // start gateway client
  305. client.start().await.unwrap();
  306. let slab = Slab::new("btc".to_string(), rnd.to_le_bytes().to_vec());
  307. client.put_slab(slab.clone()).await.unwrap();
  308. client.put_slab(slab.clone()).await.unwrap();
  309. client.put_slab(slab.clone()).await.unwrap();
  310. client.put_slab(slab.clone()).await.unwrap();
  311. client.put_slab(slab.clone()).await.unwrap();
  312. client.put_slab(slab.clone()).await.unwrap();
  313. client.put_slab(slab.clone()).await.unwrap();
  314. client.put_slab(slab.clone()).await.unwrap();
  315. client.put_slab(slab.clone()).await.unwrap();
  316. client.put_slab(slab.clone()).await.unwrap();
  317. });
  318. });
  319. // Client B
  320. let thread2 = std::thread::spawn(|| {
  321. let ex = Arc::new(Executor::new());
  322. let (signal, shutdown) = async_channel::unbounded::<()>();
  323. let ex2 = ex.clone();
  324. let (_, _) = Parallel::new()
  325. // Run four executor threads.
  326. .each(0..3, |_| smol::future::block_on(ex2.run(shutdown.recv())))
  327. // Run the main future on the current thread.
  328. .finish(|| {
  329. smol::future::block_on(async move {
  330. let connect_addr: SocketAddr = "127.0.0.1:3333".parse().unwrap();
  331. let sub_addr: SocketAddr = "127.0.0.1:4444".parse().unwrap();
  332. let mut rng = rand::thread_rng();
  333. let rnd: u32 = rng.gen();
  334. let path_str = format!("database_{}.db", rnd);
  335. let database_path = Path::new(path_str.as_str());
  336. let rocks = Rocks::new(database_path.clone()).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 subscribing
  341. let gateway_slabs_sub: GatewaySlabsSubscriber =
  342. client.start_subscriber(sub_addr, ex.clone()).await.unwrap();
  343. ex.clone()
  344. .spawn(subscribe(gateway_slabs_sub, "B".to_string()))
  345. .detach();
  346. // start gateway client
  347. client.start().await.unwrap();
  348. // sleep for 2 seconds
  349. std::thread::sleep(std::time::Duration::from_secs(2));
  350. });
  351. drop(signal);
  352. Ok::<(), drk::Error>(())
  353. });
  354. });
  355. thread_pools.push(thread);
  356. thread_pools.push(thread2);
  357. for t in thread_pools {
  358. t.join().unwrap();
  359. }
  360. }
  361. }