bitcoin_bridge.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. use rand::{thread_rng, Rng};
  2. use rand::distributions::Alphanumeric;
  3. use secp256k1::key::{SecretKey, PublicKey};
  4. use bitcoin::util::ecdsa::{PrivateKey, PublicKey as BitcoinPubKey};
  5. use bitcoin::util::{address::Payload, address::Address};
  6. // Use p2pkh for 1st iteration
  7. use bitcoin::hash_types::PubkeyHash;
  8. use bitcoin::network::constants::Network;
  9. use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request};
  10. use crate::blockchain::{rocks::columns, RocksColumn, CashierKeypair, CashierStore};
  11. use crate::{serial::deserialize, serial::serialize, Error, Result};
  12. use crate::wallet::{WalletDb, WalletPtr};
  13. use std::net::SocketAddr;
  14. use async_std::sync::Arc;
  15. use async_executor::Executor;
  16. use log::*;
  17. #[repr(u8)]
  18. enum CashierError {
  19. NoError,
  20. UpdateIndex,
  21. }
  22. #[repr(u8)]
  23. enum CashierCommand {
  24. GetDBTC,
  25. GetBTC,
  26. }
  27. pub struct BitcoinKeys {
  28. secret_key: SecretKey,
  29. bitcoin_private_key: PrivateKey,
  30. pub bitcoin_public_key: BitcoinPubKey,
  31. pub pub_address: Address,
  32. }
  33. impl BitcoinKeys {
  34. pub fn new(
  35. ) -> Result<BitcoinKeys> {
  36. let context = secp256k1::Secp256k1::new();
  37. // Probably not good enough for release
  38. let rand: String = thread_rng()
  39. .sample_iter(&Alphanumeric)
  40. .take(32)
  41. .map(char::from)
  42. .collect();
  43. let rand_hex = hex::encode(rand);
  44. // Generate simple byte array from rand
  45. let data_slice: &[u8] = rand_hex.as_bytes();
  46. let secret_key = SecretKey::from_slice(&hex::decode(data_slice).unwrap()).unwrap();
  47. //let public_key = PublicKey::from_secret_key(&context, &secret_key);
  48. // Use Testnet
  49. let bitcoin_private_key = PrivateKey::new(secret_key, Network::Testnet);
  50. let bitcoin_public_key = BitcoinPubKey::from_private_key(&context, &bitcoin_private_key);
  51. let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Testnet);
  52. Ok(Self {
  53. secret_key,
  54. bitcoin_private_key,
  55. bitcoin_public_key,
  56. pub_address,
  57. })
  58. }
  59. pub fn get_deposit_address(&self) -> &Address {
  60. &self.pub_address
  61. }
  62. }
  63. pub struct CashierService {
  64. addr: SocketAddr,
  65. cashierstore: Arc<CashierStore>,
  66. wallet: Arc<WalletDb>,
  67. }
  68. impl CashierService {
  69. pub fn new(
  70. addr: SocketAddr,
  71. rocks: RocksColumn<columns::CashierKeys>,
  72. wallet: Arc<WalletDb>,
  73. )-> Result<Arc<CashierService>> {
  74. let cashierstore = CashierStore::new(rocks)?;
  75. Ok(Arc::new(CashierService {
  76. cashierstore,
  77. addr,
  78. wallet,
  79. }))
  80. }
  81. pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  82. let service_name = String::from("CASHIER DAEMON");
  83. let mut protocol = RepProtocol::new(self.addr.clone(), service_name.clone());
  84. let (send, recv) = protocol.start().await?;
  85. let handle_request_task = executor.spawn(self.handle_request_loop(
  86. send.clone(),
  87. recv.clone(),
  88. executor.clone(),
  89. ));
  90. protocol.run(executor.clone()).await?;
  91. let _ = handle_request_task.cancel().await;
  92. Ok(())
  93. }
  94. async fn handle_request_loop(
  95. self: Arc<Self>,
  96. send_queue: async_channel::Sender<(PeerId, Reply)>,
  97. recv_queue: async_channel::Receiver<(PeerId, Request)>,
  98. executor: Arc<Executor<'_>>,
  99. ) -> Result<()> {
  100. loop {
  101. match recv_queue.recv().await {
  102. Ok(msg) => {
  103. let cashierstore = self.cashierstore.clone();
  104. let _ = executor
  105. .spawn(Self::handle_request(
  106. msg,
  107. cashierstore,
  108. send_queue.clone(),
  109. ))
  110. .detach();
  111. }
  112. Err(_) => {
  113. break;
  114. }
  115. }
  116. }
  117. Ok(())
  118. }
  119. async fn handle_request(
  120. msg: (PeerId, Request),
  121. cashierstore: Arc<CashierStore>,
  122. send_queue: async_channel::Sender<(PeerId, Reply)>,
  123. ) -> Result<()> {
  124. let request = msg.1;
  125. let peer = msg.0;
  126. match request.get_command() {
  127. 0 => {
  128. // Exchange zk_pubkey for bitcoin address
  129. let zkpub = request.get_payload();
  130. // Generate bitcoin Address
  131. let btc_keys = BitcoinKeys::new().unwrap();
  132. let deposit_address = btc_keys.get_deposit_address();
  133. let mut reply = Reply::from(&request, CashierError::NoError as u32, vec![]);
  134. // if let None = error {
  135. // reply.set_error(CashierError::UpdateIndex as u32);
  136. // }
  137. // send reply
  138. send_queue.send((peer, reply)).await?;
  139. }
  140. 1 => {
  141. // Withdraw
  142. }
  143. _ => {
  144. return Err(Error::ServicesError("received wrong command"));
  145. }
  146. }
  147. Ok(())
  148. }
  149. }
  150. pub struct CashierClient {
  151. protocol: ReqProtocol,
  152. cashierstore: Arc<CashierStore>,
  153. }
  154. impl CashierClient {
  155. pub fn new(addr: SocketAddr, rocks: RocksColumn<columns::CashierKeys>) -> Result<Self> {
  156. let protocol = ReqProtocol::new(addr, String::from("CASHIER CLIENT"));
  157. let cashierstore = CashierStore::new(rocks)?;
  158. Ok(CashierClient {
  159. protocol,
  160. cashierstore,
  161. })
  162. }
  163. pub async fn start(&mut self) -> Result<()> {
  164. self.protocol.start().await?;
  165. //self.sync().await?;
  166. Ok(())
  167. }
  168. pub async fn get_keys(&mut self, index: jubjub::SubgroupPoint) -> Result<Option<CashierKeypair>> {
  169. let rep = self
  170. .protocol
  171. .request(
  172. CashierCommand::GetDBTC as u8,
  173. serialize(&index),
  174. &handle_error,
  175. )
  176. .await?;
  177. if let Some(keys) = rep {
  178. let keys: CashierKeypair = deserialize(&keys)?;
  179. //self.gateway_slabs_sub_s.send(slab.clone()).await?;
  180. self.cashierstore.put(keys.clone())?;
  181. return Ok(Some(keys));
  182. }
  183. Ok(None)
  184. }
  185. // pub async fn put_keys(&mut self, mut keys: CashierKeys) -> Result<()> {
  186. // loop {
  187. // let last_index = self.sync().await?;
  188. // //keys.set_index(last_index + 1);
  189. // let keys = serialize(&keys);
  190. // let rep = self
  191. // .protocol
  192. // .request(CashierCommand::PutSlab as u8, slab.clone(), &handle_error)
  193. // .await?;
  194. // if let Some(_) = rep {
  195. // break;
  196. // }
  197. // }
  198. // Ok(())
  199. // }
  200. pub fn get_cashierstore(&self) -> Arc<CashierStore> {
  201. self.cashierstore.clone()
  202. }
  203. }
  204. fn handle_error(status_code: u32) {
  205. match status_code {
  206. 1 => {
  207. warn!("Reply has an Error: Index is not updated");
  208. }
  209. 2 => {
  210. warn!("Reply has an Error: Index Not Exist");
  211. }
  212. _ => {}
  213. }
  214. }