client.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. use crate::blockchain::{rocks::columns, Rocks, RocksColumn, Slab};
  2. use crate::cli::{TransferParams, WithdrawParams};
  3. use crate::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,
  10. };
  11. use crate::rpc::jsonserver;
  12. use crate::serial::Encodable;
  13. use crate::serial::{deserialize, serialize, 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, Error, Result};
  18. use super::ClientFailed;
  19. use async_executor::Executor;
  20. use bellman::groth16;
  21. use bls12_381::Bls12;
  22. use log::*;
  23. use rusqlite::Connection;
  24. use jsonrpc_core::{BoxFuture, IoHandler};
  25. use jsonrpc_derive::rpc;
  26. use async_std::sync::{Arc, Mutex};
  27. use futures::FutureExt;
  28. use std::net::SocketAddr;
  29. use std::path::PathBuf;
  30. pub struct Client {
  31. state: State,
  32. secret: jubjub::Fr,
  33. mint_params: bellman::groth16::Parameters<Bls12>,
  34. spend_params: bellman::groth16::Parameters<Bls12>,
  35. gateway: GatewayClient,
  36. }
  37. impl Client {
  38. pub fn new(
  39. secret: jubjub::Fr,
  40. rocks: Arc<Rocks>,
  41. gateway_addrs: (SocketAddr, SocketAddr),
  42. params_paths: (PathBuf, PathBuf),
  43. wallet_path: PathBuf,
  44. ) -> Result<Self> {
  45. let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
  46. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  47. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  48. let mint_params_path = params_paths.0.to_str().unwrap_or("mint.params");
  49. let spend_params_path = params_paths.1.to_str().unwrap_or("spend.params");
  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_path,
  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. secret,
  76. mint_params,
  77. spend_params,
  78. gateway,
  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(
  86. client: Client,
  87. executor: Arc<Executor<'_>>,
  88. wallet: WalletPtr,
  89. cashier_addr: SocketAddr,
  90. rpc_url: SocketAddr,
  91. ) -> Result<()> {
  92. // create cashier client
  93. debug!(target: "CLIENT", "Creating cashier client");
  94. let mut cashier_client = CashierClient::new(cashier_addr)?;
  95. // start cashier_client
  96. cashier_client.start().await?;
  97. let client_mutex = Arc::new(Mutex::new(client));
  98. let cashier_mutex = Arc::new(Mutex::new(cashier_client));
  99. let mut io = IoHandler::new();
  100. let rpcimpl = RpcUserAdapter {
  101. wallet: wallet.clone(),
  102. client: client_mutex.clone(),
  103. cashier_client: cashier_mutex.clone(),
  104. };
  105. io.extend_with(rpcimpl.to_delegate());
  106. let io = Arc::new(io);
  107. // start the rpc server
  108. debug!(target: "CLIENT", "Start RPC server");
  109. let _ = jsonserver::start(executor.clone(), rpc_url, io).await?;
  110. // start subscriber
  111. Client::connect_to_subscriber(client_mutex.clone(), executor.clone(), wallet.clone()).await?;
  112. Ok(())
  113. }
  114. pub async fn transfer(
  115. self: &mut Client,
  116. transfer_params: TransferParams,
  117. wallet: WalletPtr,
  118. ) -> Result<()> {
  119. let pub_key = transfer_params.pub_key;
  120. let address = bs58::decode(pub_key.clone())
  121. .into_vec()
  122. .map_err(|_| ClientFailed::UnvalidAddress(pub_key.clone()))?;
  123. let address: jubjub::SubgroupPoint =
  124. deserialize(&address).map_err(|_| ClientFailed::UnvalidAddress(pub_key))?;
  125. let amount = transfer_params.amount;
  126. if amount <= 0.0 {
  127. return Err(ClientFailed::UnvalidAmount(amount as u64).into());
  128. }
  129. // check if there are coins
  130. let own_coins = wallet.get_own_coins()?;
  131. if own_coins.is_empty() {
  132. return Err(ClientFailed::NotEnoughValue(0).into());
  133. }
  134. let witness = &own_coins[0].3;
  135. let merkle_path = witness.path().unwrap();
  136. // Construct a new tx spending the coin
  137. let builder = tx::TransactionBuilder {
  138. clear_inputs: vec![],
  139. inputs: vec![tx::TransactionBuilderInputInfo {
  140. merkle_path,
  141. secret: self.secret.clone(),
  142. note: own_coins[0].1.clone(),
  143. }],
  144. // We can add more outputs to this list.
  145. // The only constraint is that sum(value in) == sum(value out)
  146. outputs: vec![tx::TransactionBuilderOutputInfo {
  147. value: amount as u64,
  148. asset_id: 1,
  149. public: address,
  150. }],
  151. };
  152. // Build the tx
  153. let mut tx_data = vec![];
  154. {
  155. let tx = builder.build(&self.mint_params, &self.spend_params);
  156. tx.encode(&mut tx_data).expect("encode tx");
  157. }
  158. // build slab from the transaction
  159. let slab = Slab::new(tx_data);
  160. self.gateway.put_slab(slab).await?;
  161. Ok(())
  162. }
  163. pub async fn connect_to_subscriber(
  164. client: Arc<Mutex<Client>>,
  165. executor: Arc<Executor<'_>>,
  166. wallet: WalletPtr,
  167. ) -> Result<()> {
  168. // start subscribing
  169. debug!(target: "CLIENT", "Start subscriber");
  170. let gateway_slabs_sub: GatewaySlabsSubscriber = client
  171. .lock()
  172. .await
  173. .gateway
  174. .start_subscriber(executor.clone())
  175. .await?;
  176. loop {
  177. let slab = gateway_slabs_sub.recv().await?;
  178. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  179. let mut client = client.lock().await;
  180. let update = state_transition(&client.state, tx)?;
  181. client.state.apply(update, wallet.clone()).await?;
  182. }
  183. }
  184. }
  185. pub struct State {
  186. // The entire merkle tree state
  187. pub tree: CommitmentTree<MerkleNode>,
  188. // List of all previous and the current merkle roots
  189. // This is the hashed value of all the children.
  190. pub merkle_roots: RocksColumn<columns::MerkleRoots>,
  191. // Nullifiers prevent double spending
  192. pub nullifiers: RocksColumn<columns::Nullifiers>,
  193. // Mint verifying key used by ZK
  194. pub mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  195. // Spend verifying key used by ZK
  196. pub spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  197. // TODO: remove this
  198. wallet_path: PathBuf,
  199. }
  200. impl ProgramState for State {
  201. fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
  202. // TODO: use walletdb instead of connecting with sqlite directly
  203. let conn = Connection::open(self.wallet_path.clone()).expect("Connect to database");
  204. let mut stmt = conn
  205. .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
  206. .expect("Generate statement");
  207. stmt.exists([1i32]).expect("Read database")
  208. // do actual validity check
  209. }
  210. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  211. self.merkle_roots
  212. .key_exist(*merkle_root)
  213. .expect("Check if the merkle_root valid")
  214. }
  215. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  216. self.nullifiers
  217. .key_exist(nullifier.repr)
  218. .expect("Check if nullifier exists")
  219. }
  220. // load from disk
  221. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  222. &self.mint_pvk
  223. }
  224. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  225. &self.spend_pvk
  226. }
  227. }
  228. impl State {
  229. pub async fn apply(&mut self, update: StateUpdate, wallet: WalletPtr) -> Result<()> {
  230. // Extend our list of nullifiers with the ones from the update
  231. for nullifier in update.nullifiers {
  232. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  233. }
  234. // Update merkle tree and witnesses
  235. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  236. // Add the new coins to the merkle tree
  237. let node = MerkleNode::from_coin(&coin);
  238. self.tree.append(node).expect("Append to merkle tree");
  239. // Keep track of all merkle roots that have existed
  240. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  241. // Also update all the coin witnesses
  242. for witness in wallet.witnesses.lock().await.iter_mut() {
  243. witness.append(node).expect("Append to witness");
  244. }
  245. if let Some((note, secret)) = self.try_decrypt_note(wallet.clone(), enc_note).await {
  246. // We need to keep track of the witness for this coin.
  247. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  248. // Just as we update the merkle tree with every new coin, so we do the same with
  249. // the witness.
  250. // Derive the current witness from the current tree.
  251. // This is done right after we add our coin to the tree (but before any other
  252. // coins are added)
  253. // Make a new witness for this coin
  254. let witness = IncrementalWitness::from_tree(&self.tree);
  255. wallet.put_own_coins(coin.clone(), note.clone(), witness.clone(), secret)?;
  256. }
  257. }
  258. Ok(())
  259. }
  260. async fn try_decrypt_note(
  261. &self,
  262. wallet: WalletPtr,
  263. ciphertext: EncryptedNote,
  264. ) -> Option<(Note, jubjub::Fr)> {
  265. let secret = wallet.get_private().ok()?;
  266. match ciphertext.decrypt(&secret) {
  267. Ok(note) => {
  268. // ... and return the decrypted note for this coin.
  269. return Some((note, secret.clone()));
  270. }
  271. Err(_) => {}
  272. }
  273. // We weren't able to decrypt the note with our key.
  274. None
  275. }
  276. }
  277. /// Rpc trait
  278. #[rpc(server)]
  279. pub trait Rpc {
  280. /// Adds two numbers and returns a result
  281. #[rpc(name = "say_hello")]
  282. fn say_hello(&self) -> Result<String>;
  283. /// get key
  284. #[rpc(name = "get_key")]
  285. fn get_key(&self) -> Result<String>;
  286. /// create_wallet
  287. #[rpc(name = "create_wallet")]
  288. fn create_wallet(&self) -> Result<String>;
  289. /// key_gen
  290. #[rpc(name = "key_gen")]
  291. fn key_gen(&self) -> Result<String>;
  292. /// transfer
  293. #[rpc(name = "transfer")]
  294. fn transfer(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>>;
  295. /// withdraw
  296. #[rpc(name = "withdraw")]
  297. fn withdraw(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>>;
  298. /// deposit
  299. #[rpc(name = "deposit")]
  300. fn deposit(&self) -> BoxFuture<Result<String>>;
  301. }
  302. struct RpcUserAdapter {
  303. wallet: WalletPtr,
  304. client: Arc<Mutex<Client>>,
  305. cashier_client: Arc<Mutex<CashierClient>>,
  306. }
  307. impl RpcUserAdapter {
  308. async fn transfer_process(
  309. client: Arc<Mutex<Client>>,
  310. wallet: WalletPtr,
  311. transfer_params: TransferParams,
  312. ) -> Result<String> {
  313. let address = transfer_params.pub_key.clone();
  314. let amount = transfer_params.amount.clone();
  315. client
  316. .lock()
  317. .await
  318. .transfer(transfer_params, wallet.clone())
  319. .await?;
  320. Ok(format!("transfered {} DRK to {}", amount, address))
  321. }
  322. async fn withdraw_process(
  323. client: Arc<Mutex<Client>>,
  324. cashier_client: Arc<Mutex<CashierClient>>,
  325. wallet: WalletPtr,
  326. withdraw_params: WithdrawParams,
  327. ) -> Result<String> {
  328. let address = withdraw_params.pub_key.clone();
  329. let amount = withdraw_params.amount.clone();
  330. let drk_public = cashier_client
  331. .lock()
  332. .await
  333. .withdraw(address)
  334. .await
  335. .map_err(|err| ClientFailed::from(err))?;
  336. if let Some(drk_addr) = drk_public {
  337. let drk_addr = bs58::encode(serialize(&drk_addr)).into_string();
  338. client
  339. .lock()
  340. .await
  341. .transfer(
  342. TransferParams {
  343. pub_key: drk_addr.clone(),
  344. amount,
  345. },
  346. wallet.clone(),
  347. )
  348. .await?;
  349. return Ok(format!(
  350. "sending {} dbtc to provided address for withdrawing: {} ",
  351. amount, drk_addr
  352. ));
  353. } else {
  354. return Err(Error::from(ClientFailed::UnableToGetWithdrawAddress));
  355. }
  356. }
  357. async fn deposit_process(
  358. cashier_client: Arc<Mutex<CashierClient>>,
  359. wallet: WalletPtr,
  360. ) -> Result<String> {
  361. let deposit_addr = wallet.get_public()?;
  362. let btc_public = cashier_client
  363. .lock()
  364. .await
  365. .get_address(deposit_addr)
  366. .await
  367. .map_err(|err| ClientFailed::from(err))?;
  368. if let Some(btc_addr) = btc_public {
  369. return Ok(btc_addr.to_string());
  370. } else {
  371. return Err(Error::from(ClientFailed::UnableToGetDepositAddress));
  372. }
  373. }
  374. }
  375. impl Rpc for RpcUserAdapter {
  376. fn say_hello(&self) -> Result<String> {
  377. debug!(target: "RPC USER ADAPTER", "say_hello() [START]");
  378. Ok(String::from("hello world"))
  379. }
  380. fn get_key(&self) -> Result<String> {
  381. debug!(target: "RPC USER ADAPTER", "get_key() [START]");
  382. let key_public = self.wallet.get_public()?;
  383. let bs58_address = bs58::encode(serialize(&key_public)).into_string();
  384. Ok(bs58_address)
  385. }
  386. fn create_wallet(&self) -> Result<String> {
  387. debug!(target: "RPC USER ADAPTER", "create_wallet() [START]");
  388. self.wallet.init_db()?;
  389. Ok("wallet creation successful".into())
  390. }
  391. fn key_gen(&self) -> Result<String> {
  392. debug!(target: "RPC USER ADAPTER", "key_gen() [START]");
  393. let (public, private) = self.wallet.key_gen();
  394. debug!(target: "RPC USER ADAPTER", "Created keypair...");
  395. debug!(target: "RPC USER ADAPTER", "Attempting to write to database...");
  396. self.wallet.put_keypair(public, private)?;
  397. Ok("key generation successful".into())
  398. }
  399. fn transfer(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>> {
  400. debug!(target: "RPC USER ADAPTER", "transfer() [START]");
  401. let transfer_params = TransferParams { pub_key, amount };
  402. Self::transfer_process(self.client.clone(), self.wallet.clone(), transfer_params).boxed()
  403. }
  404. fn withdraw(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>> {
  405. debug!(target: "RPC USER ADAPTER", "withdraw() [START]");
  406. let withdraw_params = WithdrawParams { pub_key, amount };
  407. Self::withdraw_process(
  408. self.client.clone(),
  409. self.cashier_client.clone(),
  410. self.wallet.clone(),
  411. withdraw_params,
  412. )
  413. .boxed()
  414. }
  415. fn deposit(&self) -> BoxFuture<Result<String>> {
  416. debug!(target: "RPC USER ADAPTER", "deposit() [START]");
  417. Self::deposit_process(self.cashier_client.clone(), self.wallet.clone()).boxed()
  418. }
  419. }