client.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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,
  9. };
  10. use crate::rpc::adapters::{RpcClient, RpcClientAdapter};
  11. use crate::rpc::jsonserver;
  12. use crate::serial::Encodable;
  13. use crate::serial::{deserialize, Decodable};
  14. use crate::service::{CashierClient, GatewayClient, GatewaySlabsSubscriber};
  15. use crate::state::{state_transition, ProgramState, StateUpdate};
  16. use crate::wallet::WalletPtr;
  17. use crate::{tx, Result};
  18. use super::ClientFailed;
  19. use async_executor::Executor;
  20. use bellman::groth16;
  21. use bls12_381::Bls12;
  22. use log::*;
  23. use jsonrpc_core::IoHandler;
  24. use async_std::sync::{Arc, Mutex};
  25. use std::net::SocketAddr;
  26. use std::path::PathBuf;
  27. pub struct Client {
  28. pub state: State,
  29. secret: jubjub::Fr,
  30. mint_params: bellman::groth16::Parameters<Bls12>,
  31. spend_params: bellman::groth16::Parameters<Bls12>,
  32. gateway: GatewayClient,
  33. }
  34. impl Client {
  35. pub fn new(
  36. secret: jubjub::Fr,
  37. rocks: Arc<Rocks>,
  38. gateway_addrs: (SocketAddr, SocketAddr),
  39. params_paths: (PathBuf, PathBuf),
  40. wallet: WalletPtr,
  41. ) -> Result<Self> {
  42. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  43. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  44. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  45. let mint_params_path = params_paths.0.to_str().unwrap_or("mint.params");
  46. let spend_params_path = params_paths.1.to_str().unwrap_or("spend.params");
  47. // Auto create trusted ceremony parameters if they don't exist
  48. if !params_paths.0.exists() {
  49. let params = setup_mint_prover();
  50. save_params(mint_params_path, &params)?;
  51. }
  52. if !params_paths.1.exists() {
  53. let params = setup_spend_prover();
  54. save_params(spend_params_path, &params)?;
  55. }
  56. // Load trusted setup parameters
  57. let (mint_params, mint_pvk) = load_params(mint_params_path)?;
  58. let (spend_params, spend_pvk) = load_params(spend_params_path)?;
  59. let state = State {
  60. tree: CommitmentTree::empty(),
  61. merkle_roots,
  62. nullifiers,
  63. mint_pvk,
  64. spend_pvk,
  65. wallet,
  66. };
  67. // create gateway client
  68. debug!(target: "CLIENT", "Creating GatewayClient");
  69. let gateway = GatewayClient::new(gateway_addrs.0, gateway_addrs.1, slabstore)?;
  70. Ok(Self {
  71. state,
  72. secret,
  73. mint_params,
  74. spend_params,
  75. gateway,
  76. })
  77. }
  78. pub async fn start(&mut self) -> Result<()> {
  79. self.gateway.start().await?;
  80. Ok(())
  81. }
  82. pub async fn connect_to_cashier(
  83. client: Client,
  84. executor: Arc<Executor<'_>>,
  85. cashier_addr: SocketAddr,
  86. rpc_url: SocketAddr,
  87. ) -> Result<()> {
  88. // create cashier client
  89. debug!(target: "CLIENT", "Creating cashier client");
  90. let mut cashier_client = CashierClient::new(cashier_addr)?;
  91. // start cashier_client
  92. cashier_client.start().await?;
  93. let client_mutex = Arc::new(Mutex::new(client));
  94. let cashier_mutex = Arc::new(Mutex::new(cashier_client));
  95. let mut io = IoHandler::new();
  96. let rpc_client_adapter = RpcClientAdapter::new(client_mutex.clone(), cashier_mutex.clone());
  97. io.extend_with(rpc_client_adapter.to_delegate());
  98. let io = Arc::new(io);
  99. // start the rpc server
  100. debug!(target: "CLIENT", "Start RPC server");
  101. let _ = jsonserver::start(executor.clone(), rpc_url, io).await?;
  102. // start subscriber
  103. Client::connect_to_subscriber(client_mutex.clone(), executor.clone()).await?;
  104. Ok(())
  105. }
  106. pub async fn transfer(self: &mut Client, pub_key: String, amount: f64) -> Result<()> {
  107. let address = bs58::decode(pub_key.clone())
  108. .into_vec()
  109. .map_err(|_| ClientFailed::UnvalidAddress(pub_key.clone()))?;
  110. let address: jubjub::SubgroupPoint =
  111. deserialize(&address).map_err(|_| ClientFailed::UnvalidAddress(pub_key))?;
  112. if amount <= 0.0 {
  113. return Err(ClientFailed::UnvalidAmount(amount as u64).into());
  114. }
  115. // check if there are coins
  116. let own_coins = self.state.wallet.get_own_coins()?;
  117. if own_coins.is_empty() {
  118. return Err(ClientFailed::NotEnoughValue(0).into());
  119. }
  120. let witness = &own_coins[0].3;
  121. let merkle_path = witness.path().unwrap();
  122. // Construct a new tx spending the coin
  123. let builder = tx::TransactionBuilder {
  124. clear_inputs: vec![],
  125. inputs: vec![tx::TransactionBuilderInputInfo {
  126. merkle_path,
  127. secret: self.secret.clone(),
  128. note: own_coins[0].1.clone(),
  129. }],
  130. // We can add more outputs to this list.
  131. // The only constraint is that sum(value in) == sum(value out)
  132. outputs: vec![tx::TransactionBuilderOutputInfo {
  133. value: amount as u64,
  134. asset_id: 1,
  135. public: address,
  136. }],
  137. };
  138. // Build the tx
  139. let mut tx_data = vec![];
  140. {
  141. let tx = builder.build(&self.mint_params, &self.spend_params);
  142. tx.encode(&mut tx_data).expect("encode tx");
  143. }
  144. // build slab from the transaction
  145. let slab = Slab::new(tx_data);
  146. self.gateway.put_slab(slab).await?;
  147. Ok(())
  148. }
  149. pub async fn connect_to_subscriber(
  150. client: Arc<Mutex<Client>>,
  151. executor: Arc<Executor<'_>>,
  152. ) -> Result<()> {
  153. // start subscribing
  154. debug!(target: "CLIENT", "Start subscriber");
  155. let gateway_slabs_sub: GatewaySlabsSubscriber = client
  156. .lock()
  157. .await
  158. .gateway
  159. .start_subscriber(executor.clone())
  160. .await?;
  161. loop {
  162. let slab = gateway_slabs_sub.recv().await?;
  163. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  164. let mut client = client.lock().await;
  165. let update = state_transition(&client.state, tx)?;
  166. client.state.apply(update).await?;
  167. }
  168. }
  169. }
  170. pub struct State {
  171. // The entire merkle tree state
  172. pub tree: CommitmentTree<MerkleNode>,
  173. // List of all previous and the current merkle roots
  174. // This is the hashed value of all the children.
  175. pub merkle_roots: RocksColumn<columns::MerkleRoots>,
  176. // Nullifiers prevent double spending
  177. pub nullifiers: RocksColumn<columns::Nullifiers>,
  178. // Mint verifying key used by ZK
  179. pub mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  180. // Spend verifying key used by ZK
  181. pub spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  182. pub wallet: WalletPtr,
  183. }
  184. impl ProgramState for State {
  185. fn is_valid_cashier_public_key(&self, public: &jubjub::SubgroupPoint) -> bool {
  186. self.wallet
  187. .get_cashier_public_keys()
  188. .expect("Get cashier public keys")
  189. .contains(public)
  190. }
  191. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  192. self.merkle_roots
  193. .key_exist(*merkle_root)
  194. .expect("Check if the merkle_root valid")
  195. }
  196. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  197. self.nullifiers
  198. .key_exist(nullifier.repr)
  199. .expect("Check if nullifier exists")
  200. }
  201. // load from disk
  202. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  203. &self.mint_pvk
  204. }
  205. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  206. &self.spend_pvk
  207. }
  208. }
  209. impl State {
  210. pub async fn apply(&mut self, update: StateUpdate) -> Result<()> {
  211. // Extend our list of nullifiers with the ones from the update
  212. for nullifier in update.nullifiers {
  213. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  214. }
  215. // Update merkle tree and witnesses
  216. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  217. // Add the new coins to the merkle tree
  218. let node = MerkleNode::from_coin(&coin);
  219. self.tree.append(node).expect("Append to merkle tree");
  220. // Keep track of all merkle roots that have existed
  221. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  222. // Also update all the coin witnesses
  223. for (coin_id, witness) in self.wallet.get_witnesses()?.iter_mut() {
  224. witness.append(node).expect("Append to witness");
  225. self.wallet
  226. .update_witness(coin_id.clone(), witness.clone())?;
  227. }
  228. if let Some((note, secret)) = self.try_decrypt_note(enc_note).await {
  229. // We need to keep track of the witness for this coin.
  230. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  231. // Just as we update the merkle tree with every new coin, so we do the same with
  232. // the witness.
  233. // Derive the current witness from the current tree.
  234. // This is done right after we add our coin to the tree (but before any other
  235. // coins are added)
  236. // Make a new witness for this coin
  237. let witness = IncrementalWitness::from_tree(&self.tree);
  238. self.wallet
  239. .put_own_coins(coin.clone(), note.clone(), secret, witness.clone())?;
  240. }
  241. }
  242. Ok(())
  243. }
  244. async fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, jubjub::Fr)> {
  245. let secret = self.wallet.get_private().ok()?;
  246. match ciphertext.decrypt(&secret) {
  247. Ok(note) => {
  248. // ... and return the decrypted note for this coin.
  249. return Some((note, secret.clone()));
  250. }
  251. Err(_) => {}
  252. }
  253. // We weren't able to decrypt the note with our key.
  254. None
  255. }
  256. }