client.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. use crate::{
  2. blockchain::{rocks::columns, Rocks, RocksColumn, Slab},
  3. 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, OwnCoin,
  10. },
  11. serial::{Decodable, Encodable},
  12. service::{GatewayClient, GatewaySlabsSubscriber},
  13. state::{state_transition, ProgramState, StateUpdate},
  14. tx,
  15. wallet::{CashierDbPtr, Keypair, WalletPtr},
  16. Result,
  17. };
  18. use super::ClientFailed;
  19. use async_executor::Executor;
  20. use bellman::groth16;
  21. use bls12_381::Bls12;
  22. use async_std::sync::{Arc, Mutex};
  23. use log::*;
  24. use std::net::SocketAddr;
  25. use std::path::PathBuf;
  26. pub struct Client {
  27. pub state: State,
  28. mint_params: bellman::groth16::Parameters<Bls12>,
  29. spend_params: bellman::groth16::Parameters<Bls12>,
  30. gateway: GatewayClient,
  31. pub main_keypair: Keypair
  32. }
  33. impl Client {
  34. pub async fn new(
  35. rocks: Arc<Rocks>,
  36. gateway_addrs: (SocketAddr, SocketAddr),
  37. params_paths: (PathBuf, PathBuf),
  38. wallet: WalletPtr,
  39. ) -> Result<Self> {
  40. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  41. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  42. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  43. let mint_params_path = params_paths.0.to_str().unwrap_or("mint.params");
  44. let spend_params_path = params_paths.1.to_str().unwrap_or("spend.params");
  45. wallet.init_db().await?;
  46. if wallet.get_keypairs()?.len() == 0 {
  47. wallet.key_gen()?;
  48. }
  49. let main_keypair = wallet.get_keypairs()?[0].clone();
  50. // Auto create trusted ceremony parameters if they don't exist
  51. if !params_paths.0.exists() {
  52. let params = setup_mint_prover();
  53. save_params(mint_params_path, &params)?;
  54. }
  55. if !params_paths.1.exists() {
  56. let params = setup_spend_prover();
  57. save_params(spend_params_path, &params)?;
  58. }
  59. // Load trusted setup parameters
  60. let (mint_params, mint_pvk) = load_params(mint_params_path)?;
  61. let (spend_params, spend_pvk) = load_params(spend_params_path)?;
  62. let state = State {
  63. tree: CommitmentTree::empty(),
  64. merkle_roots,
  65. nullifiers,
  66. mint_pvk,
  67. spend_pvk,
  68. wallet,
  69. };
  70. // create gateway client
  71. debug!(target: "CLIENT", "Creating GatewayClient");
  72. let gateway = GatewayClient::new(gateway_addrs.0, gateway_addrs.1, slabstore)?;
  73. Ok(Self {
  74. state,
  75. mint_params,
  76. spend_params,
  77. gateway,
  78. main_keypair,
  79. })
  80. }
  81. pub async fn start(&mut self) -> Result<()> {
  82. self.gateway.start().await?;
  83. Ok(())
  84. }
  85. pub async fn connect_to_cashier(client: Client, executor: Arc<Executor<'_>>) -> Result<()> {
  86. let client_mutex = Arc::new(Mutex::new(client));
  87. // start subscriber
  88. Client::connect_to_subscriber(client_mutex.clone(), executor.clone()).await?;
  89. Ok(())
  90. }
  91. pub async fn transfer(
  92. &mut self,
  93. asset_id: jubjub::Fr,
  94. pub_key: jubjub::SubgroupPoint,
  95. amount: u64,
  96. ) -> Result<()> {
  97. if amount <= 0 {
  98. return Err(ClientFailed::InvalidAmount(amount as u64).into());
  99. }
  100. self.send(pub_key, amount, asset_id, false).await?;
  101. Ok(())
  102. }
  103. pub async fn send(
  104. &mut self,
  105. pub_key: jubjub::SubgroupPoint,
  106. amount: u64,
  107. asset_id: jubjub::Fr,
  108. clear_input: bool,
  109. ) -> Result<()> {
  110. let slab = self.build_slab_from_tx(pub_key, amount, asset_id, clear_input)?;
  111. self.gateway.put_slab(slab).await?;
  112. Ok(())
  113. }
  114. fn build_slab_from_tx(
  115. &self,
  116. pub_key: jubjub::SubgroupPoint,
  117. value: u64,
  118. asset_id: jubjub::Fr,
  119. clear_input: bool,
  120. ) -> Result<Slab> {
  121. let mut clear_inputs: Vec<tx::TransactionBuilderClearInputInfo> = vec![];
  122. let mut inputs: Vec<tx::TransactionBuilderInputInfo> = vec![];
  123. let mut outputs: Vec<tx::TransactionBuilderOutputInfo> = vec![];
  124. if clear_input {
  125. let signature_secret = self.main_keypair.private;
  126. let input = tx::TransactionBuilderClearInputInfo {
  127. value,
  128. asset_id,
  129. signature_secret,
  130. };
  131. clear_inputs.push(input);
  132. } else {
  133. inputs = self.build_inputs(value, asset_id, &mut outputs)?;
  134. }
  135. outputs.push(tx::TransactionBuilderOutputInfo {
  136. value,
  137. asset_id,
  138. public: pub_key,
  139. });
  140. let builder = tx::TransactionBuilder {
  141. clear_inputs,
  142. inputs,
  143. outputs,
  144. };
  145. let mut tx_data = vec![];
  146. {
  147. let tx = builder.build(&self.mint_params, &self.spend_params);
  148. tx.encode(&mut tx_data).expect("encode tx");
  149. }
  150. let slab = Slab::new(tx_data);
  151. Ok(slab)
  152. }
  153. fn build_inputs(
  154. &self,
  155. amount: u64,
  156. asset_id: jubjub::Fr,
  157. outputs: &mut Vec<tx::TransactionBuilderOutputInfo>,
  158. ) -> Result<Vec<tx::TransactionBuilderInputInfo>> {
  159. let mut inputs: Vec<tx::TransactionBuilderInputInfo> = vec![];
  160. let mut inputs_value: u64 = 0;
  161. let own_coins = self.state.wallet.get_own_coins()?;
  162. for own_coin in own_coins.iter() {
  163. if inputs_value >= amount {
  164. break;
  165. }
  166. let witness = &own_coin.witness;
  167. let merkle_path = witness.path().unwrap();
  168. inputs_value += own_coin.note.value;
  169. let input = tx::TransactionBuilderInputInfo {
  170. merkle_path,
  171. secret: own_coin.secret,
  172. note: own_coin.note.clone(),
  173. };
  174. inputs.push(input);
  175. }
  176. if inputs_value < amount {
  177. return Err(ClientFailed::NotEnoughValue(0).into());
  178. }
  179. if inputs_value > amount {
  180. let inputs_len = inputs.len();
  181. let input = &inputs[inputs_len - 1];
  182. let return_value: u64 = inputs_value - amount;
  183. let own_pub_key = zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.secret;
  184. outputs.push(tx::TransactionBuilderOutputInfo {
  185. value: return_value,
  186. asset_id,
  187. public: own_pub_key,
  188. });
  189. }
  190. Ok(vec![])
  191. }
  192. pub async fn connect_to_subscriber_from_cashier(
  193. client: Arc<Mutex<Client>>,
  194. executor: Arc<Executor<'_>>,
  195. cashier_wallet: CashierDbPtr,
  196. notify: async_channel::Sender<(jubjub::SubgroupPoint, u64)>,
  197. ) -> Result<()> {
  198. // start subscribing
  199. debug!(target: "CLIENT", "Start subscriber");
  200. let gateway_slabs_sub: GatewaySlabsSubscriber = client
  201. .lock()
  202. .await
  203. .gateway
  204. .start_subscriber(executor.clone())
  205. .await?;
  206. loop {
  207. let slab = gateway_slabs_sub.recv().await?;
  208. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  209. let mut client = client.lock().await;
  210. let update = state_transition(&client.state, tx)?;
  211. let mut secret_keys: Vec<jubjub::Fr> = client
  212. .state
  213. .wallet
  214. .get_keypairs()?
  215. .iter()
  216. .map(|k| k.private)
  217. .collect();
  218. let mut withdraw_keys = cashier_wallet.get_withdraw_private_keys()?;
  219. secret_keys.append(&mut withdraw_keys);
  220. client
  221. .state
  222. .apply(update, secret_keys.clone(), notify.clone())
  223. .await?;
  224. }
  225. }
  226. pub async fn connect_to_subscriber(
  227. client: Arc<Mutex<Client>>,
  228. executor: Arc<Executor<'_>>,
  229. ) -> Result<()> {
  230. // start subscribing
  231. debug!(target: "CLIENT", "Start subscriber");
  232. let gateway_slabs_sub: GatewaySlabsSubscriber = client
  233. .lock()
  234. .await
  235. .gateway
  236. .start_subscriber(executor.clone())
  237. .await?;
  238. let (notify, recv_queue) = async_channel::unbounded::<(jubjub::SubgroupPoint, u64)>();
  239. executor.spawn(async move {
  240. loop {
  241. let (pub_key, amount) = recv_queue.recv().await.expect("Receive Own Coin");
  242. debug!(target: "CLIENT", "Receive coin with following address and amount: {}, {}", pub_key, amount);
  243. }
  244. }).detach();
  245. loop {
  246. let slab = gateway_slabs_sub.recv().await?;
  247. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  248. let mut client = client.lock().await;
  249. let update = state_transition(&client.state, tx)?;
  250. let secret_keys: Vec<jubjub::Fr> = client
  251. .state
  252. .wallet
  253. .get_keypairs()?
  254. .iter()
  255. .map(|k| k.private)
  256. .collect();
  257. client
  258. .state
  259. .apply(update, secret_keys.clone(), notify.clone())
  260. .await?;
  261. }
  262. }
  263. }
  264. pub struct State {
  265. // The entire merkle tree state
  266. pub tree: CommitmentTree<MerkleNode>,
  267. // List of all previous and the current merkle roots
  268. // This is the hashed value of all the children.
  269. pub merkle_roots: RocksColumn<columns::MerkleRoots>,
  270. // Nullifiers prevent double spending
  271. pub nullifiers: RocksColumn<columns::Nullifiers>,
  272. // Mint verifying key used by ZK
  273. pub mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  274. // Spend verifying key used by ZK
  275. pub spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  276. pub wallet: WalletPtr,
  277. }
  278. impl ProgramState for State {
  279. fn is_valid_cashier_public_key(&self, public: &jubjub::SubgroupPoint) -> bool {
  280. self.wallet
  281. .get_cashier_public_keys()
  282. .expect("Get cashier public keys")
  283. .contains(public)
  284. }
  285. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  286. self.merkle_roots
  287. .key_exist(*merkle_root)
  288. .expect("Check if the merkle_root valid")
  289. }
  290. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  291. self.nullifiers
  292. .key_exist(nullifier.repr)
  293. .expect("Check if nullifier exists")
  294. }
  295. // load from disk
  296. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  297. &self.mint_pvk
  298. }
  299. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  300. &self.spend_pvk
  301. }
  302. }
  303. impl State {
  304. pub async fn apply(
  305. &mut self,
  306. update: StateUpdate,
  307. secret_keys: Vec<jubjub::Fr>,
  308. notify: async_channel::Sender<(jubjub::SubgroupPoint, u64)>,
  309. ) -> Result<()> {
  310. // Extend our list of nullifiers with the ones from the update
  311. for nullifier in update.nullifiers {
  312. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  313. }
  314. // Update merkle tree and witnesses
  315. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.iter()) {
  316. // Add the new coins to the merkle tree
  317. let node = MerkleNode::from_coin(&coin);
  318. self.tree.append(node).expect("Append to merkle tree");
  319. // Keep track of all merkle roots that have existed
  320. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  321. // Also update all the coin witnesses
  322. for (coin_id, witness) in self.wallet.get_witnesses()?.iter_mut() {
  323. witness.append(node).expect("Append to witness");
  324. self.wallet.update_witness(*coin_id, witness.clone())?;
  325. }
  326. for secret in secret_keys.iter() {
  327. if let Some(note) = Self::try_decrypt_note(enc_note, *secret) {
  328. // We need to keep track of the witness for this coin.
  329. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  330. // Just as we update the merkle tree with every new coin, so we do the same with
  331. // the witness.
  332. // Derive the current witness from the current tree.
  333. // This is done right after we add our coin to the tree (but before any other
  334. // coins are added)
  335. // Make a new witness for this coin
  336. let witness = IncrementalWitness::from_tree(&self.tree);
  337. let own_coin = OwnCoin {
  338. coin: coin.clone(),
  339. note: note.clone(),
  340. secret: *secret,
  341. witness: witness.clone(),
  342. };
  343. self.wallet.put_own_coins(own_coin)?;
  344. let pub_key = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  345. notify.send((pub_key, note.value)).await?;
  346. }
  347. }
  348. }
  349. Ok(())
  350. }
  351. fn try_decrypt_note(ciphertext: &EncryptedNote, secret: jubjub::Fr) -> Option<Note> {
  352. match ciphertext.decrypt(&secret) {
  353. // ... and return the decrypted note for this coin.
  354. Ok(note) => Some(note),
  355. // We weren't able to decrypt the note with our key.
  356. Err(_) => None,
  357. }
  358. }
  359. }