Преглед изворни кода

Merge branch 'master' of github.com:darkrenaissance/darkfi

lunar-mining пре 4 година
родитељ
комит
c75204f116
6 измењених фајлова са 160 додато и 71 уклоњено
  1. 3 0
      src/bin/drk.rs
  2. 3 10
      src/client/client.rs
  3. 29 13
      src/rpc/adapters/client_adapter.rs
  4. 88 43
      src/service/btc.rs
  5. 2 3
      src/service/cashier.rs
  6. 35 2
      todo.md

+ 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?)
     }

+ 3 - 10
src/client/client.rs

@@ -9,8 +9,8 @@ use crate::crypto::{
 };
 use crate::rpc::adapters::{RpcClient, RpcClientAdapter};
 use crate::rpc::jsonserver;
+use crate::serial::Decodable;
 use crate::serial::Encodable;
-use crate::serial::{deserialize, Decodable};
 use crate::service::{CashierClient, GatewayClient, GatewaySlabsSubscriber};
 use crate::state::{state_transition, ProgramState, StateUpdate};
 use crate::wallet::{CashierDbPtr, WalletPtr};
@@ -127,21 +127,14 @@ impl Client {
     pub async fn transfer(
         self: &mut Self,
         asset_id: u64,
-        pub_key: String,
+        pub_key: jubjub::SubgroupPoint,
         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))?;
-
         if amount <= 0.0 {
             return Err(ClientFailed::UnvalidAmount(amount as u64).into());
         }
 
-        self.send(address.clone(), amount.clone() as u64, asset_id, false)
+        self.send(pub_key.clone(), amount.clone() as u64, asset_id, false)
             .await?;
 
         Ok(())

+ 29 - 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, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture<Result<String>>;
+    fn transfer(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
 
     /// withdraw
     #[rpc(name = "withdraw")]
-    fn withdraw(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture<Result<String>>;
+    fn withdraw(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
 
     /// deposit
     #[rpc(name = "deposit")]
@@ -76,9 +76,17 @@ impl RpcClientAdapter {
     async fn transfer_process(
         client: Arc<Mutex<Client>>,
         asset_id: u64,
-        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
@@ -92,7 +100,7 @@ impl RpcClientAdapter {
         client: Arc<Mutex<Client>>,
         cashier_client: Arc<Mutex<CashierClient>>,
         asset_id: u64,
-        address: String,
+        address: Vec<u8>,
         amount: f64,
     ) -> Result<String> {
         let drk_public = cashier_client
@@ -103,8 +111,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
@@ -120,11 +126,14 @@ impl RpcClientAdapter {
         }
     }
 
-    async fn deposit_process(
+    async fn deposit_process<T>(
         client: Arc<Mutex<Client>>,
         cashier_client: Arc<Mutex<CashierClient>>,
         asset_id: u64,
-    ) -> 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()
@@ -134,7 +143,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));
         }
@@ -162,12 +172,12 @@ impl RpcClient for RpcClientAdapter {
         Self::key_gen_process(self.client.clone()).boxed()
     }
 
-    fn transfer(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture<Result<String>> {
+    fn transfer(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "transfer() [START]");
         Self::transfer_process(self.client.clone(), asset_id, pub_key, amount).boxed()
     }
 
-    fn withdraw(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture<Result<String>> {
+    fn withdraw(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "withdraw() [START]");
         Self::withdraw_process(
             self.client.clone(),
@@ -181,6 +191,12 @@ impl RpcClient for RpcClientAdapter {
 
     fn deposit(&self, asset_id: u64) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "deposit() [START]");
-        Self::deposit_process(self.client.clone(), self.cashier_client.clone(), asset_id).boxed()
+        #[cfg(feature = "default")]
+        Self::deposit_process::<bitcoin::PublicKey>(
+            self.client.clone(),
+            self.cashier_client.clone(),
+            asset_id,
+        )
+        .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

+ 35 - 2
todo.md

@@ -46,9 +46,42 @@
 - [x] darkfid: state transition function
 - [x] darkfid: send tx data to rocksdb
 
-# blockchain
+# research
 
-- [ ]
+Open research questions.
+
+## light-clients
+
+- [ ] Fast efficient batch DH technique. Currently all new transactions need to be scanned. There should be a means of efficiently batching this test for light clients initially syncing against a server.
+- [ ] Anonymouse fetch using an Oblivious-Transfer protocol. Light clients potentially leak info to servers based on the data they request, but with an OT protocol they do not reveal exactly what they are requesting.
+
+## cryptography
+
+- [ ] FFT for polynomial multiplication
+- [ ] finish bulletproofs impl
+
+## blockchain
+
+- [ ] basic sequencer architecture design
+- [ ] basic DHT design
+- [ ] consensus algorithm
+- [ ] solve double verify problem (potentially need need a payment inside the contract to handle exceptions)
+- [ ] research polygon design
+- [ ] code up a simple demo
+
+## product
+
+- [ ] first MPC services
+- [ ] DAO
+- [ ] auctions
+- [ ] staking. Look up how TORN was distributed anonymously.
+- [ ] swaps
+- [ ] token issuance
+- [ ] NFTs
+
+## dev
+
+- [ ] make bitreich halo2 impl
 
 # halo2