浏览代码

fix errors related to sterilization of addresses between rpc and cashier

ghassmo 4 年之前
父节点
当前提交
44a2d95370
共有 5 个文件被更改,包括 128 次插入68 次删除
  1. 3 0
      src/bin/drk.rs
  2. 7 9
      src/client/client.rs
  3. 28 13
      src/rpc/adapters/client_adapter.rs
  4. 88 43
      src/service/btc.rs
  5. 2 3
      src/service/cashier.rs

+ 3 - 0
src/bin/drk.rs

@@ -2,6 +2,7 @@ use std::path::PathBuf;
 
 use serde_json::json;
 
+use drk::serial::serialize;
 use drk::cli::{Config, DrkCli, DrkConfig};
 use drk::rpc::jsonrpc;
 use drk::rpc::jsonrpc::JsonResult;
@@ -86,11 +87,13 @@ impl Drk {
     }
 
     pub async fn transfer(&self, address: String, amount: f64) -> Result<()> {
+        let address = serialize(&address);
         let r = jsonrpc::request(json!("transfer"), json!([address, amount]));
         Ok(self.request("transfer", r).await?)
     }
 
     pub async fn withdraw(&self, address: String, amount: f64) -> Result<()> {
+        let address = serialize(&address);
         let r = jsonrpc::request(json!("withdraw"), json!([address, amount]));
         Ok(self.request("withdraw", r).await?)
     }

+ 7 - 9
src/client/client.rs

@@ -10,7 +10,7 @@ use crate::crypto::{
 use crate::rpc::adapters::{RpcClient, RpcClientAdapter};
 use crate::rpc::jsonserver;
 use crate::serial::Encodable;
-use crate::serial::{deserialize, Decodable};
+use crate::serial::Decodable;
 use crate::service::{CashierClient, GatewayClient, GatewaySlabsSubscriber};
 use crate::state::{state_transition, ProgramState, StateUpdate};
 use crate::wallet::{CashierDbPtr, WalletPtr};
@@ -124,19 +124,17 @@ impl Client {
         Ok(())
     }
 
-    pub async fn transfer(self: &mut Self, pub_key: String, amount: f64) -> Result<()> {
-        let address = bs58::decode(pub_key.clone())
-            .into_vec()
-            .map_err(|_| ClientFailed::UnvalidAddress(pub_key.clone()))?;
-
-        let address: jubjub::SubgroupPoint =
-            deserialize(&address).map_err(|_| ClientFailed::UnvalidAddress(pub_key))?;
+    pub async fn transfer(
+        self: &mut Self,
+        pub_key: jubjub::SubgroupPoint,
+        amount: f64,
+    ) -> Result<()> {
 
         if amount <= 0.0 {
             return Err(ClientFailed::UnvalidAmount(amount as u64).into());
         }
 
-        self.send(address.clone(), amount.clone() as u64, 1, false)
+        self.send(pub_key.clone(), amount.clone() as u64, 1, false)
             .await?;
 
         Ok(())

+ 28 - 13
src/rpc/adapters/client_adapter.rs

@@ -1,5 +1,5 @@
 use crate::client::{Client, ClientFailed};
-use crate::serial::{deserialize, serialize};
+use crate::serial::{deserialize, serialize, Decodable};
 use crate::service::CashierClient;
 use crate::{Error, Result};
 
@@ -31,11 +31,11 @@ pub trait RpcClient {
 
     /// transfer
     #[rpc(name = "transfer")]
-    fn transfer(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>>;
+    fn transfer(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
 
     /// withdraw
     #[rpc(name = "withdraw")]
-    fn withdraw(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>>;
+    fn withdraw(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
 
     /// deposit
     #[rpc(name = "deposit")]
@@ -75,9 +75,17 @@ impl RpcClientAdapter {
 
     async fn transfer_process(
         client: Arc<Mutex<Client>>,
-        address: String,
+        address: Vec<u8>,
         amount: f64,
     ) -> Result<String> {
+        let pub_key: String = deserialize(&address)?;
+        let address = bs58::decode(pub_key.clone())
+            .into_vec()
+            .map_err(|_| ClientFailed::UnvalidAddress(pub_key.clone()))?;
+
+        let address: jubjub::SubgroupPoint =
+            deserialize(&address).map_err(|_| ClientFailed::UnvalidAddress(pub_key))?;
+
         client
             .lock()
             .await
@@ -90,7 +98,7 @@ impl RpcClientAdapter {
     async fn withdraw_process(
         client: Arc<Mutex<Client>>,
         cashier_client: Arc<Mutex<CashierClient>>,
-        address: String,
+        address: Vec<u8>,
         amount: f64,
     ) -> Result<String> {
         let drk_public = cashier_client
@@ -101,8 +109,6 @@ impl RpcClientAdapter {
             .map_err(|err| ClientFailed::from(err))?;
 
         if let Some(drk_addr) = drk_public {
-            let drk_addr = bs58::encode(serialize(&drk_addr)).into_string();
-
             client
                 .lock()
                 .await
@@ -118,10 +124,13 @@ impl RpcClientAdapter {
         }
     }
 
-    async fn deposit_process(
+    async fn deposit_process<T>(
         client: Arc<Mutex<Client>>,
         cashier_client: Arc<Mutex<CashierClient>>,
-    ) -> Result<String> {
+    ) -> Result<String>
+    where
+        T: Decodable + ToString,
+    {
         let deposit_addr = client.lock().await.state.wallet.get_public_keys()?[0];
         let coin_public = cashier_client
             .lock()
@@ -131,7 +140,8 @@ impl RpcClientAdapter {
             .map_err(|err| ClientFailed::from(err))?;
 
         if let Some(coin_addr) = coin_public {
-            return Ok(deserialize(&coin_addr)?);
+            let pub_k: T = deserialize(&coin_addr)?;
+            return Ok(pub_k.to_string());
         } else {
             return Err(Error::from(ClientFailed::UnableToGetDepositAddress));
         }
@@ -159,12 +169,12 @@ impl RpcClient for RpcClientAdapter {
         Self::key_gen_process(self.client.clone()).boxed()
     }
 
-    fn transfer(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>> {
+    fn transfer(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "transfer() [START]");
         Self::transfer_process(self.client.clone(), pub_key, amount).boxed()
     }
 
-    fn withdraw(&self, pub_key: String, amount: f64) -> BoxFuture<Result<String>> {
+    fn withdraw(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "withdraw() [START]");
         Self::withdraw_process(
             self.client.clone(),
@@ -177,6 +187,11 @@ impl RpcClient for RpcClientAdapter {
 
     fn deposit(&self) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "deposit() [START]");
-        Self::deposit_process(self.client.clone(), self.cashier_client.clone()).boxed()
+        #[cfg(feature = "default")]
+        Self::deposit_process::<bitcoin::PublicKey>(
+            self.client.clone(),
+            self.cashier_client.clone(),
+        )
+        .boxed()
     }
 }

+ 88 - 43
src/service/btc.rs

@@ -1,7 +1,8 @@
-use crate::serial::{Decodable, Encodable};
-use crate::Result;
 use super::bridge::CoinClient;
+use crate::serial::{Decodable, Encodable, serialize};
+use crate::Result;
 
+use async_trait::async_trait;
 use bitcoin::blockdata::script::Script;
 use bitcoin::network::constants::Network;
 use bitcoin::util::address::Address;
@@ -11,7 +12,6 @@ use log::*;
 use rand::distributions::Alphanumeric;
 use rand::{thread_rng, Rng};
 use secp256k1::key::SecretKey;
-use async_trait::async_trait;
 
 use async_std::sync::Arc;
 use std::str::FromStr;
@@ -132,6 +132,48 @@ impl BitcoinKeys {
     }
 }
 
+
+pub struct BtcClient {
+    client: Arc<ElectrumClient>,
+}
+
+impl BtcClient {
+    pub fn new(client_address: String) -> Result<Self> {
+        let client = ElectrumClient::new(&client_address)
+            .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
+        Ok(Self {
+            client: Arc::new(client),
+        })
+    }
+}
+
+#[async_trait]
+impl CoinClient for BtcClient {
+    async fn watch(&self) -> Result<(Vec<u8>, Vec<u8>)> {
+        //// Generate bitcoin Address
+        let btc_keys = BitcoinKeys::new(self.client.clone())?;
+
+        let btc_pub = btc_keys.clone();
+        let btc_pub = btc_pub.get_pubkey();
+        let btc_priv = btc_keys.clone();
+        let btc_priv = btc_priv.get_privkey();
+
+        // let _ = btc_keys.start_subscribe().await?;
+
+        // start scheduler for checking balance
+        debug!(target: "BRIDGE BITCOIN", "Subscribing for deposit");
+        //let _script = btc_keys.get_script();
+        //
+
+        Ok((serialize(&btc_priv.to_bytes()), serialize(&btc_pub.to_bytes())))
+    }
+
+    async fn send(&self, _address: Vec<u8>, _amount: u64) -> Result<()> {
+        // TODO
+        Ok(())
+    }
+}
+
 impl Encodable for bitcoin::Address {
     fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
         let addr = self.to_string();
@@ -149,12 +191,48 @@ impl Decodable for bitcoin::Address {
     }
 }
 
+impl Encodable for bitcoin::PublicKey {
+    fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
+        let key = self.to_bytes();
+        let len = key.encode(s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for bitcoin::PublicKey {
+    fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
+        let key: Vec<u8> = Decodable::decode(&mut d)?;
+        let key = bitcoin::PublicKey::from_slice(&key)
+            .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
+        Ok(key)
+    }
+}
+
+impl Encodable for bitcoin::PrivateKey {
+    fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
+        let key = self.to_bytes();
+        let len = key.encode(s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for bitcoin::PrivateKey {
+    fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
+        let key: Vec<u8> = Decodable::decode(&mut d)?;
+        let key = bitcoin::PrivateKey::from_slice(&key, Network::Testnet)
+            .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
+        Ok(key)
+    }
+}
+
+
 #[derive(Debug)]
 pub enum BtcFailed {
     NotEnoughValue(u64),
     BadBTCAddress(String),
     ElectrumError(String),
     BtcError(String),
+    DecodeAndEncodeError(String),
 }
 
 impl std::error::Error for BtcFailed {}
@@ -169,6 +247,7 @@ impl std::fmt::Display for BtcFailed {
                 write!(f, "Unable to create Electrum Client: {}", err)
             }
             BtcFailed::ElectrumError(ref err) => write!(f, "could not parse BTC address: {}", err),
+            BtcFailed::DecodeAndEncodeError(ref err) => write!(f, "Decode and decode keys error: {}", err),
             BtcFailed::BtcError(i) => {
                 write!(f, "BtcFailed: {}", i)
             }
@@ -177,46 +256,6 @@ impl std::fmt::Display for BtcFailed {
 }
 
 
-pub struct BtcClient {
-    client: Arc<ElectrumClient>,
-}
-
-impl BtcClient {
-    pub fn new(client_address: String) -> Result<Self> {
-        let client = ElectrumClient::new(&client_address)
-            .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
-        Ok(Self {
-            client: Arc::new(client),
-        })
-    }
-}
-
-#[async_trait]
-impl CoinClient for BtcClient {
-    async fn watch(&self) -> Result<(Vec<u8>, Vec<u8>)> {
-        //// Generate bitcoin Address
-        let btc_keys = BitcoinKeys::new(self.client.clone())?;
-
-        let btc_pub = btc_keys.clone();
-        let btc_pub = btc_pub.get_pubkey();
-        let btc_priv = btc_keys.clone();
-        let btc_priv = btc_priv.get_privkey();
-
-        // let _ = btc_keys.start_subscribe().await?;
-
-        // start scheduler for checking balance
-        debug!(target: "BRIDGE BITCOIN", "Subscribing for deposit");
-        //let _script = btc_keys.get_script();
-        //
-
-        Ok((btc_priv.to_bytes(), btc_pub.to_bytes()))
-    }
-    async fn send(&self, _address: Vec<u8>, _amount: u64) -> Result<()> {
-        // TODO
-        Ok(())
-    }
-}
-
 impl From<crate::error::Error> for BtcFailed {
     fn from(err: crate::error::Error) -> BtcFailed {
         BtcFailed::BtcError(err.to_string())
@@ -234,6 +273,12 @@ impl From<electrum_client::Error> for BtcFailed {
     }
 }
 
+impl From<bitcoin::util::key::Error> for BtcFailed {
+    fn from(err: bitcoin::util::key::Error) -> BtcFailed {
+        BtcFailed::DecodeAndEncodeError(err.to_string())
+    }
+}
+
 pub type BtcResult<T> = std::result::Result<T, BtcFailed>;
 
 #[cfg(test)]

+ 2 - 3
src/service/cashier.rs

@@ -238,14 +238,13 @@ impl CashierService {
             }
             1 => {
                 debug!(target: "CASHIER DAEMON", "Received withdraw request");
-                let (asset_id, coin_address): (u64, String) = deserialize(&request.get_payload())?;
+                let (asset_id, coin_address): (u64, Vec<u8>) = deserialize(&request.get_payload())?;
                 //let btc_address: String = deserialize(&btc_address)?;
                 //let btc_address = bitcoin::util::address::Address::from_str(&btc_address)
                 //   .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
                 //
 
                 let asset_id = serialize(&asset_id);
-                let coin_address = serialize(&coin_address);
 
                 let cashier_public: jubjub::SubgroupPoint;
 
@@ -301,7 +300,7 @@ impl CashierClient {
     pub async fn withdraw(
         &mut self,
         asset_id: u64,
-        coin_address: String,
+        coin_address: Vec<u8>,
     ) -> Result<Option<jubjub::SubgroupPoint>> {
         let handle_error = Arc::new(handle_error);
         let rep = self