client.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. use async_std::sync::{Arc, Mutex};
  2. use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
  3. use log::{debug, info, trace, warn};
  4. use smol::Executor;
  5. use url::Url;
  6. use crate::{
  7. blockchain::{rocks::columns, Rocks, RocksColumn, Slab},
  8. circuit::{MintContract, SpendContract},
  9. crypto::{
  10. coin::Coin,
  11. keypair::{Keypair, PublicKey, SecretKey},
  12. merkle_node::MerkleNode,
  13. proof::ProvingKey,
  14. OwnCoin,
  15. },
  16. serial::{serialize, Decodable, Encodable},
  17. service::GatewayClient,
  18. state::{state_transition, State, StateUpdate},
  19. tx,
  20. types::DrkTokenId,
  21. wallet::{
  22. cashierdb::CashierDbPtr,
  23. walletdb::{Balances, WalletPtr},
  24. },
  25. Result,
  26. };
  27. #[derive(Debug, Clone, thiserror::Error)]
  28. pub enum ClientFailed {
  29. #[error("Here is not 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 initialized")]
  46. WalletInitialized,
  47. #[error("Keypair already exists")]
  48. KeyExists,
  49. #[error("{0}")]
  50. ClientError(String),
  51. #[error("Verify error: {0}")]
  52. VerifyError(String),
  53. #[error("Merkle tree already exists")]
  54. TreeExists,
  55. }
  56. pub type ClientResult<T> = std::result::Result<T, ClientFailed>;
  57. impl From<super::error::Error> for ClientFailed {
  58. fn from(err: super::error::Error) -> ClientFailed {
  59. ClientFailed::ClientError(err.to_string())
  60. }
  61. }
  62. impl From<crate::state::VerifyFailed> for ClientFailed {
  63. fn from(err: crate::state::VerifyFailed) -> ClientFailed {
  64. ClientFailed::VerifyError(err.to_string())
  65. }
  66. }
  67. pub struct Client {
  68. pub main_keypair: Keypair,
  69. gateway: GatewayClient,
  70. wallet: WalletPtr,
  71. mint_pk: ProvingKey,
  72. spend_pk: ProvingKey,
  73. }
  74. impl Client {
  75. pub async fn new(
  76. rocks: Arc<Rocks>,
  77. gateway_addrs: (Url, Url),
  78. wallet: WalletPtr,
  79. ) -> Result<Self> {
  80. wallet.init_db().await?;
  81. // Check if there is a default keypair
  82. if wallet.get_default_keypair().await.is_err() {
  83. // Generate a new keypair if we don't have any.
  84. if wallet.get_keypairs().await?.is_empty() {
  85. wallet.key_gen().await?;
  86. }
  87. // set the first keypair as the default one
  88. wallet.set_default_keypair(&wallet.get_keypairs().await?[0].public).await?;
  89. }
  90. // Generate merkle tree if we don't have one.
  91. if wallet.get_tree().await.is_err() {
  92. wallet.tree_gen().await?;
  93. }
  94. let main_keypair = wallet.get_default_keypair().await?;
  95. info!("Main keypair: {}", bs58::encode(&serialize(&main_keypair.public)).into_string());
  96. trace!("Creating GatewayClient");
  97. let slabstore = RocksColumn::<columns::Slabs>::new(rocks);
  98. let gateway = GatewayClient::new(gateway_addrs.0, gateway_addrs.1, slabstore)?;
  99. // TODO: These should go to a better place.
  100. debug!("Building proving key for the mint contract...");
  101. let mint_pk = ProvingKey::build(11, MintContract::default());
  102. debug!("Building proving key for the spend contract...");
  103. let spend_pk = ProvingKey::build(11, SpendContract::default());
  104. let client = Client { main_keypair, gateway, wallet, mint_pk, spend_pk };
  105. Ok(client)
  106. }
  107. pub async fn start(&mut self) -> Result<()> {
  108. self.gateway.start().await
  109. }
  110. async fn build_slab_from_tx(
  111. &mut self,
  112. pubkey: PublicKey,
  113. value: u64,
  114. token_id: DrkTokenId,
  115. clear_input: bool,
  116. state: Arc<Mutex<State>>,
  117. ) -> ClientResult<Vec<Coin>> {
  118. trace!("Begin building slab from tx");
  119. let mut clear_inputs: Vec<tx::TransactionBuilderClearInputInfo> = vec![];
  120. let mut inputs: Vec<tx::TransactionBuilderInputInfo> = vec![];
  121. let mut outputs: Vec<tx::TransactionBuilderOutputInfo> = vec![];
  122. let mut coins: Vec<Coin> = vec![];
  123. if clear_input {
  124. // TODO: FIXME:
  125. let signature_secret = self.main_keypair.secret;
  126. let input = tx::TransactionBuilderClearInputInfo { value, token_id, signature_secret };
  127. clear_inputs.push(input);
  128. } else {
  129. trace!("Start building tx inputs");
  130. let mut inputs_value = 0_u64;
  131. let state_m = state.lock().await;
  132. let own_coins = self.wallet.get_own_coins().await?;
  133. for own_coin in own_coins.iter() {
  134. if inputs_value >= value {
  135. break
  136. }
  137. let node = MerkleNode(own_coin.coin.0);
  138. let (leaf_position, merkle_path) = state_m.tree.authentication_path(&node).unwrap();
  139. // TODO: What is this counting? Is it everything or does it know to separate
  140. // different tokens?
  141. inputs_value += own_coin.note.value;
  142. let input = tx::TransactionBuilderInputInfo {
  143. leaf_position,
  144. merkle_path,
  145. secret: own_coin.secret,
  146. note: own_coin.note,
  147. };
  148. inputs.push(input);
  149. coins.push(own_coin.coin);
  150. }
  151. if inputs_value < value {
  152. return Err(ClientFailed::NotEnoughValue(inputs_value))
  153. }
  154. if inputs_value > value {
  155. let return_value: u64 = inputs_value - value;
  156. outputs.push(tx::TransactionBuilderOutputInfo {
  157. value: return_value,
  158. token_id,
  159. public: self.main_keypair.public,
  160. });
  161. }
  162. trace!("Finish building inputs");
  163. }
  164. outputs.push(tx::TransactionBuilderOutputInfo { value, token_id, public: pubkey });
  165. let builder = tx::TransactionBuilder { clear_inputs, inputs, outputs };
  166. let mut tx_data = vec![];
  167. let tx: tx::Transaction = builder.build(&self.mint_pk, &self.spend_pk)?;
  168. tx.encode(&mut tx_data).expect("encode tx");
  169. let slab = Slab::new(tx_data);
  170. trace!("Finish building slab from tx");
  171. // Check if it's valid before sending to gateway
  172. let state = &*state.lock().await;
  173. state_transition(state, tx)?;
  174. trace!("Sending slab to gateway");
  175. self.gateway.put_slab(slab).await?;
  176. trace!("Slab sent to gateway successfully");
  177. Ok(coins)
  178. }
  179. pub async fn send(
  180. &mut self,
  181. pubkey: PublicKey,
  182. amount: u64,
  183. token_id: DrkTokenId,
  184. clear_input: bool,
  185. state: Arc<Mutex<State>>,
  186. ) -> ClientResult<()> {
  187. // TODO: TOKEN debug
  188. debug!("Sending {}", amount);
  189. if amount == 0 {
  190. return Err(ClientFailed::InvalidAmount(0))
  191. }
  192. let coins = self.build_slab_from_tx(pubkey, amount, token_id, clear_input, state).await?;
  193. for coin in coins.iter() {
  194. self.wallet.confirm_spend_coin(coin).await?;
  195. }
  196. debug!("Sent {}", amount);
  197. Ok(())
  198. }
  199. pub async fn transfer(
  200. &mut self,
  201. token_id: DrkTokenId,
  202. pubkey: PublicKey,
  203. amount: u64,
  204. state: Arc<Mutex<State>>,
  205. ) -> ClientResult<()> {
  206. debug!("Start transfer {}", amount);
  207. let token_id_exists = self.wallet.token_id_exists(token_id).await?;
  208. if token_id_exists {
  209. self.send(pubkey, amount, token_id, false, state).await?;
  210. } else {
  211. return Err(ClientFailed::NotEnoughValue(amount))
  212. }
  213. debug!("Finish transfer {}", amount);
  214. Ok(())
  215. }
  216. async fn update_state(
  217. secret_keys: Vec<SecretKey>,
  218. slab: &Slab,
  219. state: Arc<Mutex<State>>,
  220. wallet: WalletPtr,
  221. notify: Option<async_channel::Sender<(PublicKey, u64)>>,
  222. ) -> Result<()> {
  223. trace!("Building tx from slab and updating the state");
  224. let payload = slab.get_payload();
  225. /*
  226. use std::io::Write;
  227. let mut file = std::fs::File::create("/tmp/payload.txt")?;
  228. file.write_all(&payload)?;
  229. */
  230. trace!("Decoding payload");
  231. let tx = tx::Transaction::decode(&payload[..])?;
  232. let update: StateUpdate;
  233. // This is separate because otherwise the mutex is never unlocked.
  234. {
  235. trace!("Acquiring state lock");
  236. let state = &*state.lock().await;
  237. update = state_transition(state, tx)?;
  238. trace!("Successfully passed state_transition");
  239. }
  240. trace!("Acquiring state lock");
  241. let mut state = state.lock().await;
  242. trace!("Trying to apply the new state");
  243. state.apply(update, secret_keys, notify, wallet).await?;
  244. trace!("Successfully passed state.apply");
  245. Ok(())
  246. }
  247. pub async fn connect_to_subscriber_from_cashier(
  248. &self,
  249. state: Arc<Mutex<State>>,
  250. cashier_wallet: CashierDbPtr,
  251. notify: async_channel::Sender<(PublicKey, u64)>,
  252. executor: Arc<Executor<'_>>,
  253. ) -> Result<()> {
  254. trace!("Start subscriber for cashier");
  255. let gateway_slabs_sub = self.gateway.start_subscriber(executor.clone()).await?;
  256. let secret_key = self.main_keypair.secret;
  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. trace!("Received new slab");
  262. let mut secret_keys = vec![secret_key];
  263. let mut withdraw_keys = cashier_wallet.get_withdraw_private_keys().await?;
  264. secret_keys.append(&mut withdraw_keys);
  265. let update_state = Self::update_state(
  266. secret_keys,
  267. &slab,
  268. state.clone(),
  269. wallet.clone(),
  270. Some(notify.clone()),
  271. )
  272. .await;
  273. if let Err(e) = update_state {
  274. warn!("Update state: {}", e);
  275. continue
  276. }
  277. }
  278. });
  279. task.detach();
  280. Ok(())
  281. }
  282. pub async fn connect_to_subscriber(
  283. &self,
  284. state: Arc<Mutex<State>>,
  285. executor: Arc<Executor<'_>>,
  286. ) -> Result<()> {
  287. trace!("Start subscriber for darkfid");
  288. let gateway_slabs_sub = self.gateway.start_subscriber(executor.clone()).await?;
  289. let secret_key = self.main_keypair.secret;
  290. let wallet = self.wallet.clone();
  291. let task: smol::Task<Result<()>> = executor.spawn(async move {
  292. loop {
  293. let slab = gateway_slabs_sub.recv().await?;
  294. trace!("Received new slab");
  295. let update_state = Self::update_state(
  296. vec![secret_key],
  297. &slab,
  298. state.clone(),
  299. wallet.clone(),
  300. None,
  301. )
  302. .await;
  303. if let Err(e) = update_state {
  304. warn!("Update state: {}", e);
  305. continue
  306. }
  307. }
  308. });
  309. task.detach();
  310. Ok(())
  311. }
  312. pub async fn init_db(&self) -> Result<()> {
  313. self.wallet.init_db().await
  314. }
  315. pub async fn get_own_coins(&self) -> Result<Vec<OwnCoin>> {
  316. self.wallet.get_own_coins().await
  317. }
  318. pub async fn confirm_spend_coin(&self, coin: &Coin) -> Result<()> {
  319. self.wallet.confirm_spend_coin(coin).await
  320. }
  321. pub async fn get_keypairs(&self) -> Result<Vec<Keypair>> {
  322. self.wallet.get_keypairs().await
  323. }
  324. pub async fn key_gen(&self) -> Result<()> {
  325. self.wallet.key_gen().await
  326. }
  327. pub async fn get_balances(&self) -> Result<Balances> {
  328. self.wallet.get_balances().await
  329. }
  330. pub async fn get_tree(&self) -> Result<BridgeTree<MerkleNode, 32>> {
  331. self.wallet.get_tree().await
  332. }
  333. }