client.rs 13 KB

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