client.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. use async_std::sync::{Arc, Mutex};
  2. use bellman::groth16;
  3. use bls12_381::Bls12;
  4. use log::*;
  5. use std::net::SocketAddr;
  6. use std::path::PathBuf;
  7. use crate::{
  8. blockchain::{rocks::columns, Rocks, RocksColumn, Slab},
  9. crypto::{
  10. load_params,
  11. merkle::{CommitmentTree, IncrementalWitness},
  12. merkle_node::MerkleNode,
  13. note::{EncryptedNote, Note},
  14. nullifier::Nullifier,
  15. save_params, setup_mint_prover, setup_spend_prover, OwnCoin,
  16. },
  17. serial::{Decodable, Encodable},
  18. service::{GatewayClient, GatewaySlabsSubscriber},
  19. state::{state_transition, ProgramState, StateUpdate},
  20. tx,
  21. wallet::{CashierDbPtr, Keypair, WalletPtr},
  22. Result,
  23. };
  24. #[derive(Debug)]
  25. pub enum ClientFailed {
  26. NotEnoughValue(u64),
  27. InvalidAddress(String),
  28. InvalidAmount(u64),
  29. UnableToGetDepositAddress,
  30. UnableToGetWithdrawAddress,
  31. DoesNotHaveCashierPublicKey,
  32. DoesNotHaveKeypair,
  33. EmptyPassword,
  34. WalletInitialized,
  35. KeyExists,
  36. ClientError(String),
  37. }
  38. pub struct Client {
  39. pub state: Arc<Mutex<State>>,
  40. mint_params: bellman::groth16::Parameters<Bls12>,
  41. spend_params: bellman::groth16::Parameters<Bls12>,
  42. gateway: GatewayClient,
  43. pub main_keypair: Keypair,
  44. }
  45. impl Client {
  46. pub async fn new(
  47. rocks: Arc<Rocks>,
  48. gateway_addrs: (SocketAddr, SocketAddr),
  49. params_paths: (PathBuf, PathBuf),
  50. wallet: WalletPtr,
  51. ) -> Result<Self> {
  52. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  53. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  54. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  55. let mint_params_path = params_paths.0.to_str().unwrap_or("mint.params");
  56. let spend_params_path = params_paths.1.to_str().unwrap_or("spend.params");
  57. wallet.init_db().await?;
  58. if wallet.get_keypairs()?.is_empty() {
  59. wallet.key_gen()?;
  60. }
  61. let main_keypair = wallet.get_keypairs()?[0].clone();
  62. // Auto create trusted ceremony parameters if they don't exist
  63. if !params_paths.0.exists() {
  64. let params = setup_mint_prover();
  65. save_params(mint_params_path, &params)?;
  66. }
  67. if !params_paths.1.exists() {
  68. let params = setup_spend_prover();
  69. save_params(spend_params_path, &params)?;
  70. }
  71. // Load trusted setup parameters
  72. let (mint_params, mint_pvk) = load_params(mint_params_path)?;
  73. let (spend_params, spend_pvk) = load_params(spend_params_path)?;
  74. let state = Arc::new(Mutex::new(State {
  75. tree: CommitmentTree::empty(),
  76. merkle_roots,
  77. nullifiers,
  78. mint_pvk,
  79. spend_pvk,
  80. wallet,
  81. }));
  82. // create gateway client
  83. debug!(target: "CLIENT", "Creating GatewayClient");
  84. let gateway = GatewayClient::new(gateway_addrs.0, gateway_addrs.1, slabstore)?;
  85. Ok(Self {
  86. state,
  87. mint_params,
  88. spend_params,
  89. gateway,
  90. main_keypair,
  91. })
  92. }
  93. pub async fn start(&mut self) -> Result<()> {
  94. self.gateway.start().await?;
  95. Ok(())
  96. }
  97. pub async fn transfer(
  98. &mut self,
  99. asset_id: jubjub::Fr,
  100. pub_key: jubjub::SubgroupPoint,
  101. amount: u64,
  102. ) -> Result<()> {
  103. debug!(target: "CLIENT", "Start transfer {}", amount);
  104. if amount == 0 {
  105. return Err(ClientFailed::InvalidAmount(amount as u64).into());
  106. }
  107. self.send(pub_key, amount, asset_id, false).await?;
  108. debug!(target: "CLIENT", "End transfer {}", amount);
  109. Ok(())
  110. }
  111. pub async fn send(
  112. &mut self,
  113. pub_key: jubjub::SubgroupPoint,
  114. amount: u64,
  115. asset_id: jubjub::Fr,
  116. clear_input: bool,
  117. ) -> Result<()> {
  118. debug!(target: "CLIENT", "Start send {}", amount);
  119. let slab = self
  120. .build_slab_from_tx(pub_key, amount, asset_id, clear_input)
  121. .await?;
  122. self.gateway.put_slab(slab).await?;
  123. debug!(target: "CLIENT", "End send {}", amount);
  124. Ok(())
  125. }
  126. async fn build_slab_from_tx(
  127. &self,
  128. pub_key: jubjub::SubgroupPoint,
  129. value: u64,
  130. asset_id: jubjub::Fr,
  131. clear_input: bool,
  132. ) -> Result<Slab> {
  133. debug!(target: "CLIENT", "Start build slab from tx");
  134. let mut clear_inputs: Vec<tx::TransactionBuilderClearInputInfo> = vec![];
  135. let mut inputs: Vec<tx::TransactionBuilderInputInfo> = vec![];
  136. let mut outputs: Vec<tx::TransactionBuilderOutputInfo> = vec![];
  137. if clear_input {
  138. let signature_secret = self.main_keypair.private;
  139. let input = tx::TransactionBuilderClearInputInfo {
  140. value,
  141. asset_id,
  142. signature_secret,
  143. };
  144. clear_inputs.push(input);
  145. } else {
  146. inputs = self.build_inputs(value, asset_id, &mut outputs).await?;
  147. }
  148. outputs.push(tx::TransactionBuilderOutputInfo {
  149. value,
  150. asset_id,
  151. public: pub_key,
  152. });
  153. let builder = tx::TransactionBuilder {
  154. clear_inputs,
  155. inputs,
  156. outputs,
  157. };
  158. let mut tx_data = vec![];
  159. {
  160. let tx = builder.build(&self.mint_params, &self.spend_params);
  161. tx.encode(&mut tx_data).expect("encode tx");
  162. }
  163. let slab = Slab::new(tx_data);
  164. debug!(target: "CLIENT", "End build slab from tx");
  165. Ok(slab)
  166. }
  167. async fn build_inputs(
  168. &self,
  169. amount: u64,
  170. asset_id: jubjub::Fr,
  171. outputs: &mut Vec<tx::TransactionBuilderOutputInfo>,
  172. ) -> Result<Vec<tx::TransactionBuilderInputInfo>> {
  173. debug!(target: "CLIENT", "Start build inputs");
  174. let mut inputs: Vec<tx::TransactionBuilderInputInfo> = vec![];
  175. let mut inputs_value: u64 = 0;
  176. let own_coins = self.state.lock().await.wallet.get_own_coins()?;
  177. for own_coin in own_coins.iter() {
  178. if inputs_value >= amount {
  179. break;
  180. }
  181. let witness = &own_coin.witness;
  182. let merkle_path = witness.path().unwrap();
  183. inputs_value += own_coin.note.value;
  184. let input = tx::TransactionBuilderInputInfo {
  185. merkle_path,
  186. secret: own_coin.secret,
  187. note: own_coin.note.clone(),
  188. };
  189. inputs.push(input);
  190. }
  191. if inputs_value < amount {
  192. return Err(ClientFailed::NotEnoughValue(inputs_value).into());
  193. }
  194. if inputs_value > amount {
  195. let inputs_len = inputs.len();
  196. let input = &inputs[inputs_len - 1];
  197. let return_value: u64 = inputs_value - amount;
  198. let own_pub_key = zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.secret;
  199. outputs.push(tx::TransactionBuilderOutputInfo {
  200. value: return_value,
  201. asset_id,
  202. public: own_pub_key,
  203. });
  204. }
  205. debug!(target: "CLIENT", "End build inputs");
  206. Ok(inputs)
  207. }
  208. pub async fn connect_to_subscriber_from_cashier(
  209. &self,
  210. cashier_wallet: CashierDbPtr,
  211. notify: async_channel::Sender<(jubjub::SubgroupPoint, u64)>,
  212. ) -> Result<()> {
  213. // start subscribing
  214. debug!(target: "CLIENT", "Start subscriber for cashier");
  215. let gateway_slabs_sub: GatewaySlabsSubscriber = self.gateway.start_subscriber().await?;
  216. let secret_key = self.main_keypair.private;
  217. let state = self.state.clone();
  218. let task: smol::Task<Result<()>> = smol::spawn(async move {
  219. loop {
  220. let slab = gateway_slabs_sub.recv().await?;
  221. debug!(target: "CLIENT", "Received new slab");
  222. debug!(target: "CLIENT", "Starting build tx from slab");
  223. let tx = tx::Transaction::decode(&slab.get_payload()[..]);
  224. if let Err(e) = tx {
  225. warn!("TX: {}", e.to_string());
  226. continue;
  227. }
  228. let mut state = state.lock().await;
  229. let update = state_transition(&state, tx?);
  230. if let Err(e) = update {
  231. warn!("state transition: {}", e.to_string());
  232. continue;
  233. }
  234. let mut secret_keys: Vec<jubjub::Fr> = vec![secret_key];
  235. let mut withdraw_keys = cashier_wallet.get_withdraw_private_keys()?;
  236. secret_keys.append(&mut withdraw_keys);
  237. state
  238. .apply(update?, secret_keys.clone(), notify.clone())
  239. .await?;
  240. }
  241. });
  242. task.detach();
  243. debug!(target: "CLIENT", "End subscriber for cashier");
  244. Ok(())
  245. }
  246. pub async fn connect_to_subscriber(&self) -> Result<()> {
  247. // start subscribing
  248. debug!(target: "CLIENT", "Start subscriber");
  249. let gateway_slabs_sub: GatewaySlabsSubscriber = self.gateway.start_subscriber().await?;
  250. let (notify, _) = async_channel::unbounded::<(jubjub::SubgroupPoint, u64)>();
  251. let secret_key = self.main_keypair.private;
  252. let state = self.state.clone();
  253. let task: smol::Task<Result<()>> = smol::spawn(async move {
  254. loop {
  255. let slab = gateway_slabs_sub.recv().await?;
  256. debug!(target: "CLIENT", "Received new slab");
  257. debug!(target: "CLIENT", "Starting build tx from slab");
  258. let tx = tx::Transaction::decode(&slab.get_payload()[..]);
  259. if let Err(e) = tx {
  260. warn!("TX: {}", e.to_string());
  261. continue;
  262. }
  263. let mut state = state.lock().await;
  264. let update = state_transition(&state, tx?);
  265. if let Err(e) = update {
  266. warn!("state transition: {}", e.to_string());
  267. continue;
  268. }
  269. let secret_keys: Vec<jubjub::Fr> = vec![secret_key];
  270. state
  271. .apply(update?, secret_keys.clone(), notify.clone())
  272. .await?;
  273. }
  274. });
  275. task.detach();
  276. Ok(())
  277. }
  278. pub async fn init_db(&self) -> Result<()> {
  279. self.state.lock().await.wallet.init_db().await
  280. }
  281. pub async fn key_gen(&self) -> Result<()> {
  282. self.state.lock().await.wallet.key_gen()
  283. }
  284. //pub async fn token_and_balances(&self) -> Result<()> {
  285. // self.state.lock().await.wallet.get_token_ids()
  286. //}
  287. pub async fn token_id_exists(&self, token_id: &jubjub::Fr) -> Result<bool> {
  288. self.state.lock().await.wallet.token_id_exists(token_id)
  289. }
  290. pub async fn get_token_id(&self) -> Result<Vec<jubjub::Fr>> {
  291. self.state.lock().await.wallet.get_token_id()
  292. }
  293. }
  294. pub struct State {
  295. // The entire merkle tree state
  296. pub tree: CommitmentTree<MerkleNode>,
  297. // List of all previous and the current merkle roots
  298. // This is the hashed value of all the children.
  299. pub merkle_roots: RocksColumn<columns::MerkleRoots>,
  300. // Nullifiers prevent double spending
  301. pub nullifiers: RocksColumn<columns::Nullifiers>,
  302. // Mint verifying key used by ZK
  303. pub mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  304. // Spend verifying key used by ZK
  305. pub spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  306. pub wallet: WalletPtr,
  307. }
  308. impl ProgramState for State {
  309. fn is_valid_cashier_public_key(&self, public: &jubjub::SubgroupPoint) -> bool {
  310. debug!(target: "CLIENT STATE", "Check if it is valid cashier public key");
  311. if let Ok(pub_keys) = self.wallet.get_cashier_public_keys() {
  312. if pub_keys.is_empty() {
  313. error!(target: "State", "No cashier public key");
  314. return false;
  315. }
  316. return pub_keys.contains(public);
  317. }
  318. false
  319. }
  320. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  321. debug!(target: "CLIENT STATE", "Check if it is valid merkle");
  322. if let Ok(mr) = self.merkle_roots.key_exist(*merkle_root) {
  323. return mr;
  324. }
  325. false
  326. }
  327. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  328. debug!(target: "CLIENT STATE", "Check if nullifier exists");
  329. if let Ok(nl) = self.nullifiers.key_exist(nullifier.repr) {
  330. return nl;
  331. }
  332. false
  333. }
  334. // load from disk
  335. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  336. &self.mint_pvk
  337. }
  338. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  339. &self.spend_pvk
  340. }
  341. }
  342. impl State {
  343. pub async fn apply(
  344. &mut self,
  345. update: StateUpdate,
  346. secret_keys: Vec<jubjub::Fr>,
  347. notify: async_channel::Sender<(jubjub::SubgroupPoint, u64)>,
  348. ) -> Result<()> {
  349. // Extend our list of nullifiers with the ones from the update
  350. debug!(target: "CLIENT STATE", "Extend nullifiers");
  351. for nullifier in update.nullifiers {
  352. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  353. }
  354. debug!(target: "CLIENT STATE", "Update merkle tree and witness ");
  355. // Update merkle tree and witnesses
  356. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.iter()) {
  357. // Add the new coins to the merkle tree
  358. let node = MerkleNode::from_coin(&coin);
  359. self.tree.append(node).expect("Append to merkle tree");
  360. debug!(target: "CLIENT STATE", "Keep track of all merkle roots");
  361. // Keep track of all merkle roots that have existed
  362. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  363. debug!(target: "CLIENT STATE", "Update witness");
  364. // Also update all the coin witnesses
  365. for (coin_id, witness) in self.wallet.get_witnesses()?.iter_mut() {
  366. witness.append(node).expect("Append to witness");
  367. self.wallet.update_witness(*coin_id, witness.clone())?;
  368. }
  369. debug!(target: "CLIENT STATE", "iterate over secret_keys to decrypt note");
  370. for secret in secret_keys.iter() {
  371. if let Some(note) = Self::try_decrypt_note(enc_note, *secret) {
  372. // We need to keep track of the witness for this coin.
  373. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  374. // Just as we update the merkle tree with every new coin, so we do the same with
  375. // the witness.
  376. // Derive the current witness from the current tree.
  377. // This is done right after we add our coin to the tree (but before any other
  378. // coins are added)
  379. // Make a new witness for this coin
  380. let witness = IncrementalWitness::from_tree(&self.tree);
  381. let own_coin = OwnCoin {
  382. coin: coin.clone(),
  383. note: note.clone(),
  384. secret: *secret,
  385. witness: witness.clone(),
  386. };
  387. self.wallet.put_own_coins(own_coin)?;
  388. let pub_key = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  389. debug!(target: "CLIENT STATE", "Received a coin: amount {} from {}", note.value, pub_key);
  390. debug!(target: "CLIENT STATE", "Send a notification");
  391. notify.send((pub_key, note.value)).await?;
  392. }
  393. }
  394. }
  395. Ok(())
  396. }
  397. fn try_decrypt_note(ciphertext: &EncryptedNote, secret: jubjub::Fr) -> Option<Note> {
  398. match ciphertext.decrypt(&secret) {
  399. // ... and return the decrypted note for this coin.
  400. Ok(note) => Some(note),
  401. // We weren't able to decrypt the note with our key.
  402. Err(_) => None,
  403. }
  404. }
  405. }
  406. impl std::error::Error for ClientFailed {}
  407. impl std::fmt::Display for ClientFailed {
  408. fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  409. match self {
  410. ClientFailed::NotEnoughValue(i) => {
  411. write!(f, "There is no enough value {}", i)
  412. }
  413. ClientFailed::InvalidAddress(i) => {
  414. write!(f, "Invalid Address {}", i)
  415. }
  416. ClientFailed::InvalidAmount(i) => {
  417. write!(f, "Invalid Amount {}", i)
  418. }
  419. ClientFailed::UnableToGetDepositAddress => f.write_str("Unable to get deposit address"),
  420. ClientFailed::UnableToGetWithdrawAddress => {
  421. f.write_str("Unable to get withdraw address")
  422. }
  423. ClientFailed::DoesNotHaveCashierPublicKey => {
  424. f.write_str("Does not have cashier public key")
  425. }
  426. ClientFailed::DoesNotHaveKeypair => f.write_str("Does not have keypair"),
  427. ClientFailed::EmptyPassword => f.write_str("Password is empty. Cannot create database"),
  428. ClientFailed::WalletInitialized => f.write_str("Wallet already initalized"),
  429. ClientFailed::KeyExists => f.write_str("Keypair already exists"),
  430. ClientFailed::ClientError(i) => {
  431. write!(f, "ClientError: {}", i)
  432. }
  433. }
  434. }
  435. }
  436. impl From<super::error::Error> for ClientFailed {
  437. fn from(err: super::error::Error) -> ClientFailed {
  438. ClientFailed::ClientError(err.to_string())
  439. }
  440. }
  441. pub type ClientResult<T> = std::result::Result<T, ClientFailed>;