client.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. use async_std::sync::{Arc, Mutex};
  2. use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
  3. use lazy_init::Lazy;
  4. use log::{debug, error, info};
  5. use super::state::{state_transition, State};
  6. use crate::{
  7. crypto::{
  8. address::Address,
  9. coin::Coin,
  10. keypair::{Keypair, PublicKey, SecretKey},
  11. merkle_node::MerkleNode,
  12. proof::ProvingKey,
  13. types::DrkTokenId,
  14. OwnCoin,
  15. },
  16. tx::{
  17. builder::{
  18. TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
  19. TransactionBuilderOutputInfo,
  20. },
  21. Transaction,
  22. },
  23. util::serial::Encodable,
  24. wallet::walletdb::{Balances, WalletPtr},
  25. zk::circuit::MintContract,
  26. ClientFailed, ClientResult, Result,
  27. };
  28. /// The Client structure, used for transaction operations.
  29. /// This includes, receiving, broadcasting, and building.
  30. pub struct Client {
  31. pub main_keypair: Mutex<Keypair>,
  32. pub wallet: WalletPtr,
  33. mint_pk: Lazy<ProvingKey>,
  34. burn_pk: Lazy<ProvingKey>,
  35. }
  36. impl Client {
  37. pub async fn new(wallet: WalletPtr) -> Result<Self> {
  38. // Initialize or load the wallet
  39. wallet.init_db().await?;
  40. // Get default keypair or create one
  41. let main_keypair = wallet.get_default_keypair_or_create_one().await?;
  42. info!(target: "client", "Main keypair: {}", Address::from(main_keypair.public));
  43. // Generate merkle tree if we don't have one.
  44. // TODO: See what to do about this
  45. if wallet.get_tree().await.is_err() {
  46. wallet.tree_gen().await?;
  47. }
  48. Ok(Self {
  49. main_keypair: Mutex::new(main_keypair),
  50. wallet,
  51. mint_pk: Lazy::new(),
  52. burn_pk: Lazy::new(),
  53. })
  54. }
  55. // TODO: Better function name
  56. async fn build_slab_from_tx(
  57. &self,
  58. pubkey: PublicKey,
  59. value: u64,
  60. token_id: DrkTokenId,
  61. clear_input: bool,
  62. state: Arc<Mutex<State>>,
  63. ) -> ClientResult<(Transaction, Vec<Coin>)> {
  64. debug!("build_slab_from_tx(): Begin building slab from tx");
  65. let mut clear_inputs = vec![];
  66. let mut inputs = vec![];
  67. let mut outputs = vec![];
  68. let mut coins = vec![];
  69. if clear_input {
  70. debug!("build_slab_from_tx(): Building clear input");
  71. let signature_secret = self.main_keypair.lock().await.secret;
  72. let input = TransactionBuilderClearInputInfo { value, token_id, signature_secret };
  73. clear_inputs.push(input);
  74. } else {
  75. debug!("build_slab_from_tx(): Building tx inputs");
  76. let mut inputs_value = 0;
  77. let state_m = state.lock().await;
  78. let own_coins = self.wallet.get_own_coins().await?;
  79. for own_coin in own_coins.iter() {
  80. if inputs_value >= value {
  81. debug!("build_slab_from_tx(): inputs_value >= value");
  82. break
  83. }
  84. let leaf_position = own_coin.leaf_position;
  85. let merkle_path = state_m.tree.authentication_path(leaf_position).unwrap();
  86. inputs_value += own_coin.note.value;
  87. let input = TransactionBuilderInputInfo {
  88. leaf_position,
  89. merkle_path,
  90. secret: own_coin.secret,
  91. note: own_coin.note,
  92. };
  93. inputs.push(input);
  94. coins.push(own_coin.coin);
  95. }
  96. // Release state lock
  97. drop(state_m);
  98. if inputs_value < value {
  99. error!("build_slab_from_tx(): Not enough value to build tx inputs");
  100. return Err(ClientFailed::NotEnoughValue(inputs_value))
  101. }
  102. if inputs_value > value {
  103. let return_value = inputs_value - value;
  104. outputs.push(TransactionBuilderOutputInfo {
  105. value: return_value,
  106. token_id,
  107. public: self.main_keypair.lock().await.public,
  108. });
  109. }
  110. debug!("build_slab_from_tx(): Finished building inputs");
  111. }
  112. outputs.push(TransactionBuilderOutputInfo { value, token_id, public: pubkey });
  113. let builder = TransactionBuilder { clear_inputs, inputs, outputs };
  114. let mut tx_data = vec![];
  115. let mint_pk = self.mint_pk.get_or_create(Client::build_mint_pk);
  116. let burn_pk = self.burn_pk.get_or_create(Client::build_burn_pk);
  117. let tx = builder.build(mint_pk, burn_pk)?;
  118. tx.encode(&mut tx_data)?;
  119. // Check if state transition is valid before broadcasting
  120. debug!("build_slab_from_tx(): Checking if state transition is valid");
  121. let state = &*state.lock().await;
  122. debug!("build_slab_from_tx(): Got state lock");
  123. state_transition(state, tx.clone())?;
  124. debug!("build_slab_from_tx(): Successful state transition");
  125. debug!("build_slab_from_tx(): Broadcasting transaction");
  126. // TODO: Send to some channel, let's not p2p here
  127. //self.p2p.broadcast(Tx(Transaction)).await?;
  128. debug!("build_slab_from_tx(): Broadcasted successfully");
  129. Ok((tx, coins))
  130. }
  131. // TODO: This was changed so it does not broadcast transactions anymore.
  132. // Instead, it returns the transaction itself, which is then able to be
  133. // arbitrarily broadcasted. Rename the function from send() to a better name.
  134. pub async fn send(
  135. &self,
  136. pubkey: PublicKey,
  137. amount: u64,
  138. token_id: DrkTokenId,
  139. clear_input: bool,
  140. state: Arc<Mutex<State>>,
  141. ) -> ClientResult<Transaction> {
  142. // TODO: Token id debug
  143. debug!("send(): Sending {}", amount);
  144. if amount == 0 {
  145. return Err(ClientFailed::InvalidAmount(0))
  146. }
  147. let (tx, coins) =
  148. self.build_slab_from_tx(pubkey, amount, token_id, clear_input, state).await?;
  149. for coin in coins.iter() {
  150. // TODO: This should be more robust. In case our transaction is denied,
  151. // we want to revert to be able to send again.
  152. self.wallet.confirm_spend_coin(coin).await?;
  153. }
  154. debug!("send(): Sent {}", amount);
  155. Ok(tx)
  156. }
  157. pub async fn transfer(
  158. &self,
  159. token_id: DrkTokenId,
  160. pubkey: PublicKey,
  161. amount: u64,
  162. state: Arc<Mutex<State>>,
  163. ) -> ClientResult<()> {
  164. debug!("transfer(): Start transfer {}", amount);
  165. if self.wallet.token_id_exists(token_id).await? {
  166. self.send(pubkey, amount, token_id, false, state).await?;
  167. debug!("transfer(): Finish transfer {}", amount);
  168. return Ok(())
  169. }
  170. Err(ClientFailed::NotEnoughValue(amount))
  171. }
  172. // TODO: Should this function run on finalized blocks and iterate over its transactions?
  173. async fn update_state(
  174. secret_keys: Vec<SecretKey>,
  175. tx: Transaction,
  176. state: Arc<Mutex<State>>,
  177. wallet: WalletPtr,
  178. notify: Option<async_channel::Sender<(PublicKey, u64)>>,
  179. ) -> Result<()> {
  180. debug!("update_state(): Begin state update");
  181. debug!("update_state(): Acquiring state lock");
  182. let update;
  183. {
  184. let state = &*state.lock().await;
  185. update = state_transition(state, tx)?;
  186. }
  187. debug!("update_state(): Trying to apply the new state");
  188. let mut state = state.lock().await;
  189. state.apply(update, secret_keys, notify, wallet).await?;
  190. drop(state);
  191. debug!("update_state(): Successfully updated state");
  192. Ok(())
  193. }
  194. pub async fn init_db(&self) -> Result<()> {
  195. self.wallet.init_db().await
  196. }
  197. pub async fn get_own_coins(&self) -> Result<Vec<OwnCoin>> {
  198. self.wallet.get_own_coins().await
  199. }
  200. pub async fn confirm_spend_coin(&self, coin: &Coin) -> Result<()> {
  201. self.wallet.confirm_spend_coin(coin).await
  202. }
  203. pub async fn get_keypairs(&self) -> Result<Vec<Keypair>> {
  204. self.wallet.get_keypairs().await
  205. }
  206. pub async fn put_keypair(&self, keypair: &Keypair) -> Result<()> {
  207. self.wallet.put_keypair(keypair).await
  208. }
  209. pub async fn set_default_keypair(&self, public: &PublicKey) -> Result<()> {
  210. let kp = self.wallet.set_default_keypair(public).await?;
  211. let mut mk = self.main_keypair.lock().await;
  212. *mk = kp;
  213. drop(mk);
  214. Ok(())
  215. }
  216. pub async fn keygen(&self) -> Result<Address> {
  217. let kp = self.wallet.keygen().await?;
  218. Ok(Address::from(kp.public))
  219. }
  220. pub async fn get_balances(&self) -> Result<Balances> {
  221. self.wallet.get_balances().await
  222. }
  223. pub async fn get_tree(&self) -> Result<BridgeTree<MerkleNode, 32>> {
  224. self.wallet.get_tree().await
  225. }
  226. fn build_mint_pk() -> ProvingKey {
  227. ProvingKey::build(11, &MintContract::default())
  228. }
  229. fn build_burn_pk() -> ProvingKey {
  230. ProvingKey::build(11, &MintContract::default())
  231. }
  232. }