Prechádzať zdrojové kódy

continue works on issue #35

ghassmo 4 rokov pred
rodič
commit
b0fc31ead2

+ 45 - 0
bin/cashier/src/error.rs

@@ -0,0 +1,45 @@
+pub type Result<T> = std::result::Result<T, Error>;
+
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum Error {
+    /// Service
+    #[error("Services Error: `{0}`")]
+    ServicesError(&'static str),
+    #[error("Client failed: `{0}`")]
+    ClientFailed(String),
+    #[cfg(feature = "btc")]
+    #[error(transparent)]
+    BtcFailed(#[from] crate::service::BtcFailed),
+    #[cfg(feature = "sol")]
+    #[error("Sol client failed: `{0}`")]
+    SolFailed(String),
+    #[cfg(feature = "eth")]
+    #[error(transparent)]
+    EthFailed(#[from] crate::service::EthFailed),
+    #[error("BridgeError Error: `{0}`")]
+    BridgeError(String),
+
+    #[error("Async_channel sender error")]
+    AsyncChannelSenderError,
+    #[error(transparent)]
+    AsyncChannelReceiverError(#[from] async_channel::RecvError),
+}
+
+#[cfg(feature = "sol")]
+impl From<crate::service::SolFailed> for Error {
+    fn from(err: crate::service::SolFailed) -> Error {
+        Error::SolFailed(err.to_string())
+    }
+}
+
+impl From<darkfi::Error> for Error {
+    fn from(err: darkfi::Error) -> Error {
+        Error::ClientFailed(err.to_string())
+    }
+}
+
+impl<T> From<async_channel::SendError<T>> for Error {
+    fn from(_err: async_channel::SendError<T>) -> Error {
+        Error::AsyncChannelSenderError
+    }
+}

+ 1 - 0
bin/cashier/src/lib.rs

@@ -1 +1,2 @@
+pub mod error;
 pub mod service;

+ 13 - 11
bin/cashier/src/main.rs

@@ -43,10 +43,10 @@ use cashier::service::{bridge, bridge::Bridge};
 
 fn handle_bridge_error(error_code: u32) -> Result<()> {
     match error_code {
-        1 => Err(Error::BridgeError("Not Supported Client".into())),
-        2 => Err(Error::BridgeError("Unable to watch the deposit address".into())),
-        3 => Err(Error::BridgeError("Unable to send the token".into())),
-        _ => Err(Error::BridgeError("Unknown error_code".into())),
+        1 => Err(Error::CashierError("Not Supported Client".into())),
+        2 => Err(Error::CashierError("Unable to watch the deposit address".into())),
+        3 => Err(Error::CashierError("Unable to send the token".into())),
+        _ => Err(Error::CashierError("Unknown error_code".into())),
     }
 }
 
@@ -123,7 +123,7 @@ impl Cashierd {
                 #[cfg(feature = "sol")]
                 NetworkName::Solana => {
                     debug!(target: "CASHIER DAEMON", "Adding solana network");
-                    use drk::service::SolClient;
+                    use cashier::service::SolClient;
 
                     let _bridge = self.bridge.clone();
 
@@ -141,7 +141,7 @@ impl Cashierd {
                 NetworkName::Ethereum => {
                     debug!(target: "CASHIER DAEMON", "Adding ethereum network");
 
-                    use drk::service::EthClient;
+                    use cashier::service::EthClient;
 
                     let _bridge = self.bridge.clone();
 
@@ -161,7 +161,7 @@ impl Cashierd {
                 #[cfg(feature = "btc")]
                 NetworkName::Bitcoin => {
                     debug!(target: "CASHIER DAEMON", "Adding bitcoin network");
-                    use drk::service::btc::BtcClient;
+                    use cashier::service::btc::BtcClient;
 
                     let _bridge = self.bridge.clone();
 
@@ -292,7 +292,9 @@ impl Cashierd {
                         .await?;
                 }
                 _ => {
-                    return Err(Error::BridgeError("Receive unknown value from Subscription".into()))
+                    return Err(Error::CashierError(
+                        "Receive unknown value from Subscription".into(),
+                    ))
                 }
             }
         }
@@ -304,7 +306,7 @@ impl Cashierd {
         match network {
             #[cfg(feature = "sol")]
             NetworkName::Solana => {
-                use drk::service::sol::SOL_NATIVE_TOKEN_ID;
+                use cashier::service::sol::SOL_NATIVE_TOKEN_ID;
                 if _token_id != SOL_NATIVE_TOKEN_ID {
                     return Ok(Some(_token_id.to_string()))
                 }
@@ -312,7 +314,7 @@ impl Cashierd {
             }
             #[cfg(feature = "eth")]
             NetworkName::Ethereum => {
-                use drk::service::eth::ETH_NATIVE_TOKEN_ID;
+                use cashier::service::eth::ETH_NATIVE_TOKEN_ID;
                 if _token_id != ETH_NATIVE_TOKEN_ID {
                     return Ok(Some(_token_id.to_string()))
                 }
@@ -438,7 +440,7 @@ impl Cashierd {
                     Ok(token_key.public_key)
                 }
                 bridge::BridgeResponsePayload::Address(token_pub) => Ok(token_pub),
-                _ => Err(Error::BridgeError("Receive unknown value from Subscription".into())),
+                _ => Err(Error::CashierError("Receive unknown value from Subscription".into())),
             }
         }
         .await;

+ 42 - 25
bin/cashier/src/service/btc.rs

@@ -339,7 +339,7 @@ impl BtcClient {
                     .put_main_keys(
                         &TokenKey {
                             secret_key: serialize(&main_keypair),
-                            public_key: serialize(&main_keypair.pubkey()),
+                            public_key: serialize(&SecPublicKey(main_keypair.pubkey())),
                         },
                         &NetworkName::Bitcoin,
                     )
@@ -518,12 +518,13 @@ impl BtcClient {
         )?;
 
         let _txid = signed_tx.txid();
+        let signed_tx = BtcTransaction(signed_tx);
         let _serialized_tx = serialize(&signed_tx);
 
         info!(target: "BTC BRIDGE", "Signed tx: {:?}",
-            serialize_hex(&signed_tx));
+            serialize_hex(&signed_tx.0));
 
-        let txid = electrum.transaction_broadcast_raw(&signed_tx.serialize().to_vec())?;
+        let txid = electrum.transaction_broadcast_raw(&signed_tx.0.serialize().to_vec())?;
 
         info!(target: "BTC BRIDGE", "Sent {} satoshi to main wallet, txid: {}", amount, txid);
         Ok(())
@@ -595,7 +596,7 @@ impl NetworkClient for BtcClient {
     ) -> Result<()> {
         // address is not a btc address, so derive the btc address
         let electrum = &self.client.lock().await.electrum;
-        let public_key = deserialize(&address)?;
+        let public_key = deserialize::<SecPublicKey>(&address)?.0;
         let script_pubkey = Account::derive_btc_script_pubkey(public_key, self.network);
 
         let main_script_pubkey = &self.main_account.script_pubkey;
@@ -751,76 +752,84 @@ impl fmt::Display for ScriptStatus {
         }
     }
 }
-impl Encodable for bitcoin::Transaction {
+
+// Aliases
+pub struct BtcTransaction(bitcoin::Transaction);
+pub struct BtcAddress(bitcoin::Address);
+pub struct BtcPublicKey(bitcoin::PublicKey);
+pub struct BtcPrivateKey(bitcoin::PrivateKey);
+pub struct SecPublicKey(secp256k1::key::PublicKey);
+
+impl Encodable for BtcTransaction {
     fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let tx = self.serialize();
+        let tx = self.0.serialize();
         let len = tx.encode(s)?;
         Ok(len)
     }
 }
-impl Encodable for bitcoin::Address {
+impl Encodable for BtcAddress {
     fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let addr = self.to_string();
+        let addr = self.0.to_string();
         let len = addr.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for bitcoin::Address {
+impl Decodable for BtcAddress {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let addr: String = Decodable::decode(&mut d)?;
         let addr = bitcoin::Address::from_str(&addr)
             .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
-        Ok(addr)
+        Ok(BtcAddress(addr))
     }
 }
 
-impl Encodable for bitcoin::PublicKey {
+impl Encodable for BtcPublicKey {
     fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let key = self.to_bytes();
+        let key = self.0.to_bytes();
         let len = key.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for bitcoin::PublicKey {
+impl Decodable for BtcPublicKey {
     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| darkfi::Error::from(BtcFailed::from(err)))?;
-        Ok(key)
+        Ok(BtcPublicKey(key))
     }
 }
 
-impl Encodable for bitcoin::PrivateKey {
+impl Encodable for BtcPrivateKey {
     fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let key: String = self.to_string();
+        let key: String = self.0.to_string();
         let len = key.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for bitcoin::PrivateKey {
+impl Decodable for BtcPrivateKey {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: String = Decodable::decode(&mut d)?;
         let key = bitcoin::PrivateKey::from_str(&key)
             .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
-        Ok(key)
+        Ok(BtcPrivateKey(key))
     }
 }
-impl Encodable for secp256k1::key::PublicKey {
+impl Encodable for SecPublicKey {
     fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let key: Vec<u8> = self.serialize().to_vec();
+        let key: Vec<u8> = self.0.serialize().to_vec();
         let len = key.encode(s)?;
         Ok(len)
     }
 }
-impl Decodable for secp256k1::key::PublicKey {
+impl Decodable for SecPublicKey {
     fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
         let key: Vec<u8> = Decodable::decode(&mut d)?;
         let key = secp256k1::key::PublicKey::from_slice(&key)
             .map_err(|err| darkfi::Error::from(BtcFailed::from(err)))?;
-        Ok(key)
+        Ok(SecPublicKey(key))
     }
 }
 // TODO: add secret + public keys together for Encodable
@@ -892,6 +901,12 @@ impl From<anyhow::Error> for BtcFailed {
     }
 }
 
+impl From<BtcFailed> for Error {
+    fn from(error: BtcFailed) -> Self {
+        Error::CashierError(error.to_string())
+    }
+}
+
 pub type BtcResult<T> = std::result::Result<T, BtcFailed>;
 
 #[cfg(test)]
@@ -903,7 +918,7 @@ mod tests {
 
     use darkfi::serial::{deserialize, serialize};
 
-    use super::Keypair;
+    use super::*;
 
     const KEYPAIR_LENGTH: usize = SECRET_KEY_SIZE + PUBLIC_KEY_SIZE;
 
@@ -912,10 +927,12 @@ mod tests {
         let btc_addr =
             bitcoin::Address::from_str(&String::from("mxVFsFW5N4mu1HPkxPttorvocvzeZ7KZyk"))?;
 
+        let btc_addr = BtcAddress(btc_addr);
+
         let btc_ser = serialize(&btc_addr);
-        let btc_dser = deserialize(&btc_ser)?;
+        let btc_dser = deserialize::<BtcAddress>(&btc_ser)?.0;
 
-        assert_eq!(btc_addr, btc_dser);
+        assert_eq!(btc_addr.0, btc_dser);
 
         Ok(())
     }

+ 6 - 0
bin/cashier/src/service/eth.rs

@@ -546,6 +546,12 @@ impl From<serde_json::Error> for EthFailed {
     }
 }
 
+impl From<EthFailed> for Error {
+    fn from(error: EthFailed) -> Self {
+        Error::CashierError(error.to_string())
+    }
+}
+
 pub type EthResult<T> = std::result::Result<T, EthFailed>;
 
 #[allow(unused_imports)]

+ 42 - 37
bin/cashier/src/service/sol.rs

@@ -12,9 +12,9 @@ use solana_client::{blockhash_query::BlockhashQuery, rpc_client::RpcClient};
 use solana_sdk::{
     native_token::{lamports_to_sol, sol_to_lamports},
     program_pack::Pack,
-    pubkey::Pubkey as SolPubkey,
+    pubkey::Pubkey,
     signature::{Signature, Signer},
-    signer::keypair::Keypair as SolKeypair,
+    signer::keypair::Keypair,
     system_instruction,
     transaction::Transaction,
 };
@@ -31,15 +31,14 @@ use darkfi::{
         expand_path, generate_id2, load_keypair_to_str,
         parse::truncate,
         rpc::{jsonrpc, jsonrpc::JsonResult, websockets, websockets::WsStream},
-        sleep, NetworkName,
+        sleep, Error, NetworkName, Result,
     },
-    Error, Result,
 };
 
 pub const SOL_NATIVE_TOKEN_ID: &str = "So11111111111111111111111111111111111111112";
 
-struct Keypair(SolKeypair);
-struct Pubkey(SolPubkey);
+struct SolKeypair(Keypair);
+struct SolPubkey(Pubkey);
 
 #[derive(Serialize)]
 struct SubscribeParams {
@@ -65,34 +64,37 @@ impl SolClient {
     ) -> Result<Arc<Self>> {
         let notify_channel = async_channel::unbounded();
 
-        let main_keypair: Keypair;
+        let main_keypair: SolKeypair;
 
         let main_keypairs = cashier_wallet.get_main_keys(&NetworkName::Solana).await?;
 
         if keypair_path.is_empty() {
             if main_keypairs.is_empty() {
-                main_keypair = Keypair::new();
+                main_keypair = SolKeypair(Keypair::new());
                 cashier_wallet
                     .put_main_keys(
                         &TokenKey {
                             secret_key: serialize(&main_keypair),
-                            public_key: serialize(&main_keypair.pubkey()),
+                            public_key: serialize(&SolPubkey(main_keypair.0.pubkey())),
                         },
                         &NetworkName::Solana,
                     )
                     .await?;
             } else {
-                main_keypair = deserialize(&main_keypairs[main_keypairs.len() - 1].secret_key)?;
+                main_keypair =
+                    deserialize::<SolKeypair>(&main_keypairs[main_keypairs.len() - 1].secret_key)?;
             }
         } else {
             let keypair_str = load_keypair_to_str(expand_path(keypair_path)?)?;
 
             let keypair_bytes: Vec<u8> = serde_json::from_str(&keypair_str)?;
-            main_keypair = Keypair::from_bytes(&keypair_bytes)
-                .map_err(|e| SolFailed::Signature(e.to_string()))?;
+            main_keypair = SolKeypair(
+                Keypair::from_bytes(&keypair_bytes)
+                    .map_err(|e| SolFailed::Signature(e.to_string()))?,
+            );
         }
 
-        info!(target: "SOL BRIDGE", "Main SOL wallet pubkey: {:?}", &main_keypair.pubkey());
+        info!(target: "SOL BRIDGE", "Main SOL wallet pubkey: {:?}", &main_keypair.0.pubkey());
 
         let (rpc_server, wss_server) = match network {
             "mainnet" => ("https://api.mainnet-beta.solana.com", "wss://api.devnet.solana.com"),
@@ -103,7 +105,7 @@ impl SolClient {
         };
 
         Ok(Arc::new(Self {
-            main_keypair,
+            main_keypair: main_keypair.0,
             subscriptions: Arc::new(Mutex::new(Vec::new())),
             notify_channel,
             rpc_server,
@@ -439,9 +441,9 @@ impl NetworkClient for SolClient {
         mint_address: Option<String>,
         executor: Arc<Executor<'_>>,
     ) -> Result<TokenSubscribtion> {
-        let keypair = Keypair::new();
+        let keypair = SolKeypair(Keypair::new());
 
-        let public_key = keypair.pubkey().to_string();
+        let public_key = keypair.0.pubkey().to_string();
         let private_key = serialize(&keypair);
 
         let mint = self.check_mint_address(mint_address)?;
@@ -455,7 +457,7 @@ impl NetworkClient for SolClient {
 
         executor
             .spawn(async move {
-                let result = self.handle_subscribe_request(keypair, drk_pub_key, mint).await;
+                let result = self.handle_subscribe_request(keypair.0, drk_pub_key, mint).await;
                 if let Err(e) = result {
                     error!(target: "SOL BRIDGE SUBSCRIPTION","{}", e.to_string());
                 }
@@ -474,7 +476,7 @@ impl NetworkClient for SolClient {
         mint_address: Option<String>,
         executor: Arc<Executor<'_>>,
     ) -> Result<String> {
-        let keypair: Keypair = deserialize(&private_key)?;
+        let keypair: Keypair = deserialize::<SolKeypair>(&private_key)?.0;
 
         let public_key = keypair.pubkey().to_string();
 
@@ -511,7 +513,7 @@ impl NetworkClient for SolClient {
         debug!(target: "SOL BRIDGE", "start sending {} sol", lamports_to_sol(amount) );
 
         let rpc = RpcClient::new(self.rpc_server.to_string());
-        let address: Pubkey = deserialize(&address)?;
+        let address: Pubkey = deserialize::<SolPubkey>(&address)?.0;
 
         let mut decimals = 9;
 
@@ -582,41 +584,38 @@ pub fn sign_and_send_transaction(
     }
 }
 
-impl Encodable for Keypair {
-    fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let key: Vec<u8> = self.to_bytes().to_vec();
+impl Encodable for SolKeypair {
+    fn encode<S: std::io::Write>(&self, s: S) -> darkfi::Result<usize> {
+        let key: Vec<u8> = self.0.to_bytes().to_vec();
         let len = key.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for Keypair {
-    fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
+impl Decodable for SolKeypair {
+    fn decode<D: std::io::Read>(mut d: D) -> darkfi::Result<Self> {
         let key: Vec<u8> = Decodable::decode(&mut d)?;
-        let key = Keypair::from_bytes(key.as_slice()).map_err(|_| {
-            darkfi::Error::from(SolFailed::DecodeAndEncodeError("load keypair from slice".into()))
-        })?;
-        Ok(key)
+        let key = Keypair::from_bytes(key.as_slice())
+            .map_err(|_| darkfi::Error::DecodeError("SOL BRIDGE: load keypair from slice"))?;
+        Ok(SolKeypair(key))
     }
 }
 
-impl Encodable for Pubkey {
-    fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
-        let key = self.to_string();
+impl Encodable for SolPubkey {
+    fn encode<S: std::io::Write>(&self, s: S) -> darkfi::Result<usize> {
+        let key = self.0.to_string();
         let len = key.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for Pubkey {
-    fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
+impl Decodable for SolPubkey {
+    fn decode<D: std::io::Read>(mut d: D) -> darkfi::Result<Self> {
         let key: String = Decodable::decode(&mut d)?;
         let key = Pubkey::try_from(key.as_str()).map_err(|_| {
-            darkfi::Error::from(SolFailed::DecodeAndEncodeError(
-                "load public key from slice".into(),
-            ))
+            darkfi::Error::DecodeError("SOL BRIDGE: load public key from slice".into())
         })?;
-        Ok(key)
+        Ok(SolPubkey(key))
     }
 }
 
@@ -652,4 +651,10 @@ pub enum SolFailed {
     Darkfi(#[from] darkfi::error::Error),
 }
 
+impl From<SolFailed> for Error {
+    fn from(error: SolFailed) -> Self {
+        Error::CashierError(error.to_string())
+    }
+}
+
 pub type SolResult<T> = std::result::Result<T, SolFailed>;

+ 6 - 20
src/util/error.rs

@@ -17,6 +17,10 @@ pub enum Error {
     /// Parsing And Encode/Decode errors
     #[error("parse failed: `{0}`")]
     ParseFailed(&'static str),
+    #[error("decode failed: `{0}`")]
+    DecodeError(&'static str),
+    #[error("encode failed: `{0}`")]
+    EncodeError(&'static str),
     #[error(transparent)]
     ParseIntError(#[from] std::num::ParseIntError),
     #[error(transparent)]
@@ -89,17 +93,8 @@ pub enum Error {
     ServicesError(&'static str),
     #[error("Client failed: `{0}`")]
     ClientFailed(String),
-    #[cfg(feature = "btc")]
-    #[error(transparent)]
-    BtcFailed(#[from] crate::service::BtcFailed),
-    #[cfg(feature = "sol")]
-    #[error("Sol client failed: `{0}`")]
-    SolFailed(String),
-    #[cfg(feature = "eth")]
-    #[error(transparent)]
-    EthFailed(#[from] crate::service::EthFailed),
-    #[error("BridgeError Error: `{0}`")]
-    BridgeError(String),
+    #[error("Cashier failed: `{0}`")]
+    CashierError(String),
     #[error("ZmqError: `{0}`")]
     ZmqError(String),
 
@@ -144,8 +139,6 @@ pub enum Error {
     ConfigNotFound,
     #[error("No keypair file detected.")]
     KeypairPathNotFound,
-    #[error("No cashier public keys detected.")]
-    CashierKeysNotFound,
     #[error("SetLoggerError")]
     SetLoggerError,
     #[error("Async_channel sender error")]
@@ -234,13 +227,6 @@ impl From<tungstenite::Error> for Error {
     }
 }
 
-#[cfg(feature = "sol")]
-impl From<crate::service::SolFailed> for Error {
-    fn from(err: crate::service::SolFailed) -> Error {
-        Error::SolFailed(err.to_string())
-    }
-}
-
 impl From<halo2::plonk::Error> for Error {
     fn from(err: halo2::plonk::Error) -> Error {
         Error::PlonkError(format!("{:?}", err))