client.rs 17 KB

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